日本免费精品_最新日韩一区_亚洲视频一区在线_a在线视频观看_天天射夜夜骑_粉嫩av一区二区三区_欧美中日韩免费视频_综合图区欧美_国内精品美女在线观看_午夜精品久久久久久久男人的天堂

首頁 > 系統 > Android > 正文

Android自定義View的實現方法,帶你一步步深入了解View(四)

2019-11-09 18:04:54
字體:
來源:轉載
供稿:網友

不知不覺中,帶你一步步深入了解View系列的文章已經寫到第四篇了,回顧一下,我們一共學習了LayoutInflater的原理分析、視圖的繪制流程、視圖的狀態及重繪等知識,算是把View中很多重要的知識點都涉及到了。如果你還沒有看過我前面的幾篇文章,建議先去閱讀一下,多了解一些原理方面的東西。

之前我有承諾過,會在View這個話題上多寫幾篇博客,講一講View的工作原理,以及自定義View的方法。現在前半部分的承諾已經如約兌現了,那么今天我就要來兌現后面部分的承諾,講一講自定義View的實現方法,同時這也是帶你一步步深入了解View系列的完結篇。

一些接觸Android不久的朋友對自定義View都有一絲畏懼感,總感覺這是一個比較高級的技術,但其實自定義View并不復雜,有時候只需要簡單幾行代碼就可以完成了。

如果說要按類型來劃分的話,自定義View的實現方式大概可以分為三種,自繪控件、組合控件、以及繼承控件。那么下面我們就來依次學習一下,每種方式分別是如何自定義View的。

一、自繪控件

自繪控件的意思就是,這個View上所展現的內容全部都是我們自己繪制出來的。繪制的代碼是寫在onDraw()方法中的,而這部分內容我們已經在 Android視圖繪制流程完全解析,帶你一步步深入了解View(二)  中學習過了。

下面我們準備來自定義一個計數器View,這個View可以響應用戶的點擊事件,并自動記錄一共點擊了多少次。新建一個CounterView繼承自View,代碼如下所示:

public class CounterView extends View implements OnClickListener {	PRivate Paint mPaint;		private Rect mBounds;	private int mCount;		public CounterView(Context context, AttributeSet attrs) {		super(context, attrs);		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);		mBounds = new Rect();		setOnClickListener(this);	}	@Override	protected void onDraw(Canvas canvas) {		super.onDraw(canvas);		mPaint.setColor(Color.BLUE);		canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);		mPaint.setColor(Color.YELLOW);		mPaint.setTextSize(30);		String text = String.valueOf(mCount);		mPaint.getTextBounds(text, 0, text.length(), mBounds);		float textWidth = mBounds.width();		float textHeight = mBounds.height();		canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2				+ textHeight / 2, mPaint);	}	@Override	public void onClick(View v) {		mCount++;		invalidate();	}}可以看到,首先我們在CounterView的構造函數中初始化了一些數據,并給這個View的本身注冊了點擊事件,這樣當CounterView被點擊的時候,onClick()方法就會得到調用。而onClick()方法中的邏輯就更加簡單了,只是對mCount這個計數器加1,然后調用invalidate()方法。通過 Android視圖狀態及重繪流程分析,帶你一步步深入了解View(三)  這篇文章的學習我們都已經知道,調用invalidate()方法會導致視圖進行重繪,因此onDraw()方法在稍后就將會得到調用。

既然CounterView是一個自繪視圖,那么最主要的邏輯當然就是寫在onDraw()方法里的了,下面我們就來仔細看一下。這里首先是將Paint畫筆設置為藍色,然后調用Canvas的drawRect()方法繪制了一個矩形,這個矩形也就可以當作是CounterView的背景圖吧。接著將畫筆設置為黃色,準備在背景上面繪制當前的計數,注意這里先是調用了getTextBounds()方法來獲取到文字的寬度和高度,然后調用了drawText()方法去進行繪制就可以了。

這樣,一個自定義的View就已經完成了,并且目前這個CounterView是具備自動計數功能的。那么剩下的問題就是如何讓這個View在界面上顯示出來了,其實這也非常簡單,我們只需要像使用普通的控件一樣來使用CounterView就可以了。比如在布局文件中加入如下代碼:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <com.example.customview.CounterView        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_centerInParent="true" /></RelativeLayout>可以看到,這里我們將CounterView放入了一個RelativeLayout中,然后可以像使用普通控件來給CounterView指定各種屬性,比如通過layout_width和layout_height來指定CounterView的寬高,通過android:layout_centerInParent來指定它在布局里居中顯示。只不過需要注意,自定義的View在使用的時候一定要寫出完整的包名,不然系統將無法找到這個View。

好了,就是這么簡單,接下來我們可以運行一下程序,并不停地點擊CounterView,效果如下圖所示。

怎么樣?是不是感覺自定義View也并不是什么高級的技術,簡單幾行代碼就可以實現了。當然了,這個CounterView功能非常簡陋,只有一個計數功能,因此只需幾行代碼就足夠了,當你需要繪制比較復雜的View時,還是需要很多技巧的。

二、組合控件

組合控件的意思就是,我們并不需要自己去繪制視圖上顯示的內容,而只是用系統原生的控件就好了,但我們可以將幾個系統原生的控件組合到一起,這樣創建出的控件就被稱為組合控件。

舉個例子來說,標題欄就是個很常見的組合控件,很多界面的頭部都會放置一個標題欄,標題欄上會有個返回按鈕和標題,點擊按鈕后就可以返回到上一個界面。那么下面我們就來嘗試去實現這樣一個標題欄控件。

新建一個title.xml布局文件,代碼如下所示:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="50dp"    android:background="#ffcb05" >    <Button        android:id="@+id/button_left"        android:layout_width="60dp"        android:layout_height="40dp"        android:layout_centerVertical="true"        android:layout_marginLeft="5dp"        android:background="@drawable/back_button"        android:text="Back"        android:textColor="#fff" />    <TextView        android:id="@+id/title_text"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:text="This is Title"        android:textColor="#fff"        android:textSize="20sp" /></RelativeLayout>

在這個布局文件中,我們首先定義了一個RelativeLayout作為背景布局,然后在這個布局里定義了一個Button和一個TextView,Button就是標題欄中的返回按鈕,TextView就是標題欄中的顯示的文字。

接下來創建一個TitleView繼承自FrameLayout,代碼如下所示:

public class TitleView extends FrameLayout {	private Button leftButton;	private TextView titleText;	public TitleView(Context context, AttributeSet attrs) {		super(context, attrs);		LayoutInflater.from(context).inflate(R.layout.title, this);		titleText = (TextView) findViewById(R.id.title_text);		leftButton = (Button) findViewById(R.id.button_left);		leftButton.setOnClickListener(new OnClickListener() {			@Override			public void onClick(View v) {				((Activity) getContext()).finish();			}		});	}	public void setTitleText(String text) {		titleText.setText(text);	}	public void setLeftButtonText(String text) {		leftButton.setText(text);	}	public void setLeftButtonListener(OnClickListener l) {		leftButton.setOnClickListener(l);	}}TitleView中的代碼非常簡單,在TitleView的構建方法中,我們調用了LayoutInflater的inflate()方法來加載剛剛定義的title.xml布局,這部分內容我們已經在 Android LayoutInflater原理分析,帶你一步步深入了解View(一)  這篇文章中學習過了。

接下來調用findViewById()方法獲取到了返回按鈕的實例,然后在它的onClick事件中調用finish()方法來關閉當前的Activity,也就相當于實現返回功能了。

另外,為了讓TitleView有更強地擴展性,我們還提供了setTitleText()、setLeftButtonText()、setLeftButtonListener()等方法,分別用于設置標題欄上的文字、返回按鈕上的文字、以及返回按鈕的點擊事件。

到了這里,一個自定義的標題欄就完成了,那么下面又到了如何引用這個自定義View的部分,其實方法基本都是相同的,在布局文件中添加如下代碼:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <com.example.customview.TitleView        android:id="@+id/title_view"        android:layout_width="match_parent"        android:layout_height="wrap_content" >    </com.example.customview.TitleView></RelativeLayout>

這樣就成功將一個標題欄控件引入到布局文件中了,運行一下程序,效果如下圖所示:

現在點擊一下Back按鈕,就可以關閉當前的Activity了。如果你想要修改標題欄上顯示的內容,或者返回按鈕的默認事件,只需要在Activity中通過findViewById()方法得到TitleView的實例,然后調用setTitleText()、setLeftButtonText()、setLeftButtonListener()等方法進行設置就OK了。

三、繼承控件

繼承控件的意思就是,我們并不需要自己重頭去實現一個控件,只需要去繼承一個現有的控件,然后在這個控件上增加一些新的功能,就可以形成一個自定義的控件了。這種自定義控件的特點就是不僅能夠按照我們的需求加入相應的功能,還可以保留原生控件的所有功能,比如  Android PowerImageView實現,可以播放動畫的強大ImageView  這篇文章中介紹的PowerImageView就是一個典型的繼承控件。

為了能夠加深大家對這種自定義View方式的理解,下面我們再來編寫一個新的繼承控件。ListView相信每一個Android程序員都一定使用過,這次我們準備對ListView進行擴展,加入在ListView上滑動就可以顯示出一個刪除按鈕,點擊按鈕就會刪除相應數據的功能。

首先需要準備一個刪除按鈕的布局,新建delete_button.xml文件,代碼如下所示:

<?xml version="1.0" encoding="utf-8"?><Button xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/delete_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:background="@drawable/delete_button" ></Button>這個布局文件很簡單,只有一個按鈕而已,并且我們給這個按鈕指定了一張刪除背景圖。

接著創建MyListView繼承自ListView,這就是我們自定義的View了,代碼如下所示:

public class MyListView extends ListView implements OnTouchListener,		OnGestureListener {	private GestureDetector gestureDetector;	private OnDeleteListener listener;	private View deleteButton;	private ViewGroup itemLayout;	private int selectedItem;	private boolean isDeleteShown;	public MyListView(Context context, AttributeSet attrs) {		super(context, attrs);		gestureDetector = new GestureDetector(getContext(), this);		setOnTouchListener(this);	}	public void setOnDeleteListener(OnDeleteListener l) {		listener = l;	}	@Override	public boolean onTouch(View v, MotionEvent event) {		if (isDeleteShown) {			itemLayout.removeView(deleteButton);			deleteButton = null;			isDeleteShown = false;			return false;		} else {			return gestureDetector.onTouchEvent(event);		}	}	@Override	public boolean onDown(MotionEvent e) {		if (!isDeleteShown) {			selectedItem = pointToPosition((int) e.getX(), (int) e.getY());		}		return false;	}	@Override	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,			float velocityY) {		if (!isDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) {			deleteButton = LayoutInflater.from(getContext()).inflate(					R.layout.delete_button, null);			deleteButton.setOnClickListener(new OnClickListener() {				@Override				public void onClick(View v) {					itemLayout.removeView(deleteButton);					deleteButton = null;					isDeleteShown = false;					listener.onDelete(selectedItem);				}			});			itemLayout = (ViewGroup) getChildAt(selectedItem					- getFirstVisiblePosition());			RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);			params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);			params.addRule(RelativeLayout.CENTER_VERTICAL);			itemLayout.addView(deleteButton, params);			isDeleteShown = true;		}		return false;	}	@Override	public boolean onSingleTapUp(MotionEvent e) {		return false;	}	@Override	public void onShowPress(MotionEvent e) {	}	@Override	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,			float distanceY) {		return false;	}	@Override	public void onLongPress(MotionEvent e) {	}		public interface OnDeleteListener {		void onDelete(int index);	}}由于代碼邏輯比較簡單,我就沒有加注釋。這里在MyListView的構造方法中創建了一個GestureDetector的實例用于監聽手勢,然后給MyListView注冊了touch監聽事件。然后在onTouch()方法中進行判斷,如果刪除按鈕已經顯示了,就將它移除掉,如果刪除按鈕沒有顯示,就使用GestureDetector來處理當前手勢。

當手指按下時,會調用OnGestureListener的onDown()方法,在這里通過pointToPosition()方法來判斷出當前選中的是ListView的哪一行。當手指快速滑動時,會調用onFling()方法,在這里會去加載delete_button.xml這個布局,然后將刪除按鈕添加到當前選中的那一行item上。注意,我們還給刪除按鈕添加了一個點擊事件,當點擊了刪除按鈕時就會回調onDeleteListener的onDelete()方法,在回調方法中應該去處理具體的刪除操作。

好了,自定義View的功能到此就完成了,接下來我們需要看一下如何才能使用這個自定義View。首先需要創建一個ListView子項的布局文件,新建my_list_view_item.xml,代碼如下所示:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:descendantFocusability="blocksDescendants"    android:orientation="vertical" >    <TextView        android:id="@+id/text_view"        android:layout_width="wrap_content"        android:layout_height="50dp"        android:layout_centerVertical="true"        android:gravity="left|center_vertical"        android:textColor="#000" /></RelativeLayout>然后創建一個適配器MyAdapter,在這個適配器中去加載my_list_view_item布局,代碼如下所示:
public class MyAdapter extends ArrayAdapter<String> {	public MyAdapter(Context context, int textViewResourceId, List<String> objects) {		super(context, textViewResourceId, objects);	}	@Override	public View getView(int position, View convertView, ViewGroup parent) {		View view;		if (convertView == null) {			view = LayoutInflater.from(getContext()).inflate(R.layout.my_list_view_item, null);		} else {			view = convertView;		}		TextView textView = (TextView) view.findViewById(R.id.text_view);		textView.setText(getItem(position));		return view;	}}到這里就基本已經完工了,下面在程序的主布局文件里面引入MyListView這個控件,如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <com.example.customview.MyListView        android:id="@+id/my_list_view"        android:layout_width="match_parent"        android:layout_height="wrap_content" >    </com.example.customview.MyListView></RelativeLayout>最后在Activity中初始化MyListView中的數據,并處理了onDelete()方法的刪除邏輯,代碼如下所示:
public class MainActivity extends Activity {	private MyListView myListView;	private MyAdapter adapter;	private List<String> contentList = new ArrayList<String>();	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		requestWindowFeature(Window.FEATURE_NO_TITLE);		setContentView(R.layout.activity_main);		initList();		myListView = (MyListView) findViewById(R.id.my_list_view);		myListView.setOnDeleteListener(new OnDeleteListener() {			@Override			public void onDelete(int index) {				contentList.remove(index);				adapter.notifyDataSetChanged();			}		});		adapter = new MyAdapter(this, 0, contentList);		myListView.setAdapter(adapter);	}	private void initList() {		contentList.add("Content Item 1");		contentList.add("Content Item 2");		contentList.add("Content Item 3");		contentList.add("Content Item 4");		contentList.add("Content Item 5");		contentList.add("Content Item 6");		contentList.add("Content Item 7");		contentList.add("Content Item 8");		contentList.add("Content Item 9");		contentList.add("Content Item 10");		contentList.add("Content Item 11");		contentList.add("Content Item 12");		contentList.add("Content Item 13");		contentList.add("Content Item 14");		contentList.add("Content Item 15");		contentList.add("Content Item 16");		contentList.add("Content Item 17");		contentList.add("Content Item 18");		contentList.add("Content Item 19");		contentList.add("Content Item 20");	}}這樣就把整個例子的代碼都完成了,現在運行一下程序,會看到MyListView可以像ListView一樣,正常顯示所有的數據,但是當你用手指在MyListView的某一行上快速滑動時,就會有一個刪除按鈕顯示出來,如下圖所示: 

點擊一下刪除按鈕就可以將第6行的數據刪除了。此時的MyListView不僅保留了ListView原生的所有功能,還增加了一個滑動進行刪除的功能,確實是一個不折不扣的繼承控件。

到了這里,我們就把自定義View的幾種實現方法全部講完了,雖然每個例子都很簡單,但是萬變不離其宗,復雜的View也是由這些簡單的原理堆積出來的。經過了四篇文章的學習,相信每個人對View的理解都已經較為深入了,那么帶你一步步深入了解View系列的文章就到此結束,感謝大家有耐心看到最后。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
日韩精品国产欧美| 在线一区二区三区精品| 自拍日韩亚洲一区在线| 欧美日韩国产一区中文午夜| 日韩中文字幕综合| 99日韩精品| 欧美日韩国产一二| 国产成人精品亚洲| 国产卡1卡2卡三卡在线| 中文字幕在线欧美| 国产婷婷一区二区| 欧美日韩国产中文| 亚洲乱码中文字幕综合| 中文字幕综合在线| 亚洲成年网站在线观看| 91精品日本| 日韩国产亚洲欧美| 国产欧美日韩在线| 日韩欧美中文在线| 一区二区精品免费| 九九精品调教| 福利在线国产| 国产真实乱子伦精品视频| 日韩在线视频免费观看| 日韩在线一区二区| 亚洲成av人片| 99精品视频国产| 亚洲综合在线不卡| 国产字幕在线看| 日韩欧美在线综合网| 日韩欧美三级| 国产欧美中文字幕| 国产乱国产乱老熟300| 91精品国产91久久久久久久久| 亚洲高清在线观看一区| 日韩免费电影网站| 国产丝袜欧美中文另类| 精品国产1区2区3区| 国产在线播放一区二区| 91精品国产日韩91久久久久久| 午夜av一区| 免费精品国产自产拍在| 99在线国产| 亚洲一级网站| 中文字幕在线视频网| 国产一区免费视频| 亚洲欧洲一区二区天堂久久| 久草中文在线观看| 不卡中文一二三区| 国产欧美日韩最新| 精品久久久精品| 99久久精品国产亚洲| 欧美日韩中文字幕在线观看| 国产视频2区| 国产在线观看91| 91精品在线免费观看| 国产黄色片大全| 国产三级精品在线观看| 91精品国产日韩91久久久久久| 免费国产h视频在线观看86| 欧美在线观看视频一区| 92久久精品| 亚洲综合在线不卡| 在线国产三级| av免费在线播放| 欧美激情一区二区在线| 亚洲第一视频网站| 欧美国产中文| 尤物av一区二区| 欧美熟妇乱码在线一区| 成年人看的羞羞网站| 国产黄色在线免费观看| 日韩国产高清一区| 国产无套粉嫩白浆在线2022年| 亚洲免费精品视频| 国产欧美综合在线| 国产www在线观看| 日韩欧美色综合| 在线亚洲免费| 日韩精品在线观看视频| 精品国产欧美| 免费高清在线一区| 福利一区二区| 日韩精品一级| 一区二区视频免费看| 国产一二三区精品视频| 黄色片免费在线| 日韩亚洲欧美中文在线| 中文字幕日韩高清| 91精品国产日韩91久久久久久| 中文在线а√在线8| 91精品在线视频观看| 中文字幕国产亚洲| 欧美三级在线播放| 欧美久久综合性欧美| 国产日韩第一页v| 免费精品国产自产拍在| 精品在线91| 欧美日韩中国免费专区在线看| 日本一级一片免费视频| 综合图区亚洲白拍在线| 日韩专区视频网站| 婷婷综合福利| 91亚洲国产高清| 日韩欧美国产黄色| 亚洲免费看av| 精品亚洲国内自在自线福利| 亚洲第一视频在线观看| 免费看ww视频网站入口| 日韩va亚洲va欧洲va国产| 91精品婷婷国产综合久久竹菊| 久久久水蜜桃| 999精品在线| 久久手机免费观看| 天天综合日日夜夜精品| 日韩欧美中文视频| 久久综合九色欧美综合狠狠| 精品国产欧美成人夜夜嗨| 黄色一区二区在线| 国产成人精品999在线观看| 日本va欧美va精品发布| 天堂在线中文| 欧美日韩中文字幕精品| 国产1卡2卡三卡四卡网站| 中文字幕在线观看精品| 欧美日韩久久不卡| 亚洲乱码中文字幕| 国产久卡久卡久卡久卡视频精品| 一区二区三区在线免费 | 欧美日韩激情一区二区三区| 国产精品一区二三区| 天堂精品高清1区2区3区| 伊人网站在线| 国产成人一二三区| 在线免费视频一区二区| 日韩欧美综合| 97视频在线| 国产 欧美 在线| 日韩国产高清一区| 国产激情久久| 91麻豆精品国产91久久久使用方法 | 国产偷国产偷亚洲清高网站| av一区二区高清| 亚亚洲欧洲精品| 国产手机精品视频| 国产绿帽一区二区三区| 亚洲欧美小说国产图片| 久久人人88| 日韩精品在线观看视频| 成人精品视频一区| 国产成人精品亚洲| 国产99在线 | 亚洲| 最近高清中文在线字幕在线观看| 最近中文字幕在线中文视频| 日本亚洲欧美三级| 中文在线不卡视频| 中文字幕高清在线播放| 日韩免费视频| 亚洲a中文字幕| a级在线免费观看| 日韩欧美一级在线播放| 久久精品免费看| 99久久www免费| 国产成人精品网址| 国内精品99| 1024国产在线| 久久久99免费| 99精品人妻国产毛片| 91久久精品国产| 天天综合天天做| 极品久久久久久| 欧美日韩中文国产| 色妇色综合久久夜夜| 国产资源中文字幕| 久久 天天综合| 99久久精品国产亚洲| 一区二区三区久久| 一区二区不卡视频在线观看| 黄色片免费看| 欧美婷婷精品激情| 中文字幕欧美日韩| 在线亚洲人成| 91精品999| 国产性一级片| 日韩欧美亚洲视频| 欧美日韩精品免费看| 国产福利一区二区在线精品| 日韩欧美国产三级| 欧美日韩高清| 亚洲成年人影院在线| 日韩精品丝袜在线| 成年人黄国产| 亚洲一区在线观看网站| 国产第一页在线播放| 99视频在线看| 在线观看国产一级片| 激情五月综合| 日韩欧美专区在线| 精品三区视频| 91精品国产91| 一区免费在线| 日韩av二区| 国产福利三区| 一区二区视频在线| 久久99精品久久久久子伦| 91最新在线| 二区视频在线观看| 国产福利久久| 日韩欧美一级二级三级久久久| 91久久视频| 国产黄色一区| a级在线免费观看| 日韩欧美在线不卡| 欧美.日韩.国产.一区.二区| 一级片免费网站| 中文字幕在线视频久| 最近中文字幕日韩精品| 国产激情在线视频| 综合图区亚洲白拍在线| 日韩欧美一级精品久久| 中文字幕 亚洲一区| 九一久久久久久| 99久久精品国产亚洲| 国产精久久久久| 国产小视频在线观看| 中文字幕人成乱码在线观看| 国产三级视频在线播放线观看| 九九视频精品免费| 国产欧美日韩综合| a天堂在线资源| aaa欧美日韩| 亚洲一级影院| 日韩国产高清一区| 国产美女主播视频一区| 国产天堂素人系列在线视频| 香蕉av一区| 亚洲国产欧美91| av免费观看国产| 亚洲校园欧美国产另类| 欧美日韩国产在线看| 亚洲视频一二三四| 国产在线观看黄色| 精品视频三区| 免费视频久久| 久久婷婷国产| 亚洲高清不卡一区| 国产欧美中文字幕| 91久久精品国产| 韩国av一区二区| 亚洲第一网中文字幕| 一区精品在线播放| 日韩久久不卡| 亚洲一区在线观看网站| av亚洲免费| 美女黄a一级视频| 久久婷婷综合国产| 欧美在线日韩在线| 欧美成人vr18sexvr| 亚洲一区激情| 日韩精品一区二区三区视频播放| 欧美日韩在线播放三区四区| 一区二区91| 免费视频二区| 婷婷综合福利| 在线视频日韩欧美| 欧美日韩精品在线观看| 国产农村妇女精品一二区| 日韩精品在线免费观看| 亚洲欧美日本另类| 精品欧美久久久| 国产h片在线观看| 在线日韩中文字幕| 国产三级精品在线观看| 国产福利在线播放| 视频一区中文字幕国产| 一区二区三区在线|网站| 国产一卡二卡3卡4卡四卡在线| 69堂精品视频在线播放| 天天综合日日夜夜精品| 日韩精品―中文字幕| 欧美日韩中国免费专区在线看| 婷婷久久综合九色国产成人| 国产在线二区| 欧美亚洲国产免费| 国产一区在线精品| 中文字幕日韩在线观看| 精品成人久久久| 国产在线黄色| 久久精品久久精品亚洲人| 韩国一区二区av| 精品网站999www| 午夜福利一区二区三区| 日韩欧美高清在线视频| 国产高清大尺度一区二区不卡| 伊人伊成久久人综合网小说| 成人禁用看黄a在线| 欧美日韩国产免费| 99在线国产| 日韩免费视频一区二区视频在线观看 | 欧美婷婷久久| 欧美三级网址| 日韩视频一区| 在线看欧美日韩| 黄色一区二区在线观看| 国产拍揄自揄精品视频麻豆| xxxxx性| 日韩欧美中文字幕在线观看| 日本熟女一区二区| 午夜亚洲福利| 欧美午夜影院在线视频| 刘玥91精选国产在线观看| 日韩在线视频免费观看高清中文| 久久精品久久久久| 欧美日韩精品国产| 99精品在线播放| 国产黄在线播放| 国产日产一区二区| 国产 欧美在线| 国产亚洲二区| 日本中文字幕在线观看| 精品一二三四| 欧美久久久久久蜜桃| 三级网站免费观看| 欧美日韩国产一区在线| 日韩精品福利视频| 91精品国产综合久久精品| 日韩欧美中文在线| 亚洲一级网站| 欧美激情一区二区在线| 国产嫩草影院久久久久| 欧美亚洲另类制服自拍| 国产福利第一页| 久久婷婷综合国产| 一区二区视频在线| 97久久精品午夜一区二区| 国产黄色在线| 中文字幕日韩精品在线| 福利在线国产| 99久热re在线精彩视频| 黄色一区二区在线| 中文字幕精品视频在线| 中文字幕久久精品| 在线视频第一页| 亚洲第一中文字幕在线观看| 久久久99免费| 久久夜色精品国产噜噜亚洲av| 一区二区三区在线|网站| 91精品国产91| 欧美久久综合性欧美| 欧美日韩性视频| 午夜国产在线视频| 一级片免费网站| 999精品在线| 精品一区二区三区中文字幕在线| 999精品网| a视频免费在线观看| 一二三区精品福利视频| 最近中文字幕第一页| 国产成人精品免费网站| 亚洲一区中文字幕在线| 91精品视频播放| 亚洲一区资源| 色www精品视频在线观看| 精品久久蜜桃| 欧美 日韩 中文字幕| 亚洲国产午夜精品| 亚洲中午字幕| 亚洲成在线观看| 日韩欧美亚洲日产国| 本道综合精品| 中文字幕成人乱码在线电影| 国产欧美日韩高清| 国产不卡视频在线| 日韩视频精品在线| 日本亚洲视频在线| 亚洲免费中文字幕| 日韩欧中文字幕| 不卡视频一区二区三区| 中文字幕第一页在线| 日韩精品a在线观看91| 一区二区三区在线|网站| 中文字幕乱码在线| 日本а中文在线天堂| 国产小视频在线观看免费| 日韩精品国产欧美| 精品久久电影| 欧美日韩国产片| 久久精品网站免费观看| 久久精品卡一| 日韩在线中文字幕| 中文字幕在线视频网| 国产视频1区| 欧美日韩国产高清视频| 欧美三级日韩在线| 激情国产在线| 欧美日韩综合在线免费观看| 亚洲第一视频| 日韩一级精品| 日韩欧美高清在线| 久久婷婷综合国产|