精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

玩轉(zhuǎn)Android嵌套滾動

移動開發(fā) Android
在Android UI開發(fā)過程中,經(jīng)常會遇到嵌套滾動的需求,所謂嵌套滾動,就是父view可以滾動的情況下子view也可以滾動,例如下拉刷新(PullToRefresh)。

Android

在Android UI開發(fā)過程中,經(jīng)常會遇到嵌套滾動的需求,所謂嵌套滾動,就是父view可以滾動的情況下子view也可以滾動,例如下拉刷新(PullToRefresh)。在微信讀書之前的版本中,書籍討論圈有一個比較復(fù)雜的嵌套滾動的例子,我把它抽取出來作為今天講解的例子:   

書籍討論圈有一個比較復(fù)雜的嵌套滾動 

這個例子的嵌套比較復(fù)雜,上方的header為書籍封面,下方是一個ViewPager+TabLayout組成的容器(下文簡稱VT容器),ViewPager中的三個item為三個列表,也是可以滾動的。業(yè)務(wù)需求是:

  1. VT容器可以滾動;
  2. 書籍封面可以滾動,并且有視差;
  3. 當(dāng)VT容器滾動到頂部時,滾動列表,并且滾動可以銜接。
  4. 當(dāng)列表滾動到頂部時,可以滾動書籍封面以及VT容器,并且滾動可以銜接

邏輯清楚了,接下來就看如何實(shí)現(xiàn)了。在android5以前,對于這種滾動,我們只能選擇自己去攔截事件并處理,但在后面的某個版本,android推出了NestingScroll機(jī)制,開發(fā)者的日子就好過多了,并且android提供了一個非常好的容器類:CoordinatorLayout,極大的簡化了開發(fā)者的工作。當(dāng)然我們也需要投入精力去學(xué)習(xí)并運(yùn)用這些新的Api了。

當(dāng)然,我們也要知道如果沒有這些API,我們應(yīng)當(dāng)如何去實(shí)現(xiàn)這些效果。因此本文會用三種方式去實(shí)現(xiàn)這個效果:

  1. 純事件攔截與派發(fā)方案
  2. 基于NestingScroll機(jī)制的實(shí)現(xiàn)方案
  3. 基于CoordinatorLayout與Behavior方案的實(shí)現(xiàn)

示例代碼放在Github上,可以clone下來結(jié)合文章觀看

純事件攔截與派發(fā)方案

這是最為原始的方案,當(dāng)然也靈活性***的了。其它的方案原理上都是系統(tǒng)基于它提供的封裝。使用這種方案時,我們需要解決以下幾個問題:

  1. view的滾動(Scroller);
  2. view的速度追蹤(VelocityTracker);
  3. 當(dāng)VT容器滾動到頂部時,我們?nèi)绾螌⑹录鬟f給ListView?
  4. 當(dāng)ListView滾動到頂部時,VT容器如何攔截到事件?

1、2兩點(diǎn)屬于滾動的基礎(chǔ)知識,這里不會做細(xì)致的講解。而第3點(diǎn)為何會出現(xiàn)呢?因?yàn)閍ndroid系統(tǒng)在事件派發(fā)時,如果事件被攔截,那么之后的事件都將不會傳遞給子view了。其解決方案也很簡單:在滾動到頂部時主動派發(fā)一次Down事件:

  1. if (mTargetCurrentOffset + dy <= mTargetEndOffset) { 
  2.     moveTargetView(dy); 
  3.     // 重新dispatch一次down事件,使得列表可以繼續(xù)滾動 
  4.     int oldAction = ev.getAction(); 
  5.     ev.setAction(MotionEvent.ACTION_DOWN); 
  6.     dispatchTouchEvent(ev); 
  7.     ev.setAction(oldAction); 
  8. else { 
  9.     moveTargetView(dy); 
  10.  

那么第4點(diǎn)是什么問題呢?這里就需要清楚一個坑點(diǎn)了:不是所用的事件都會走入onInterceptTouchEvent。有一種情況是子View主動調(diào)用parent.requestDisallowInterceptTouchEvent(true)來告訴系統(tǒng)說:這個事件我要了,父View不要攔截了。這就是所謂的內(nèi)部攔截法。在ListView的某些時刻它會去調(diào)用這個方法。因此一旦事件傳遞給了ListView,外部容器就拿不到這個事件了。因此我們要打破它的內(nèi)部攔截:

  1. @Override 
  2. public void requestDisallowInterceptTouchEvent(boolean b) { 
  3.     // 去掉默認(rèn)行為,使得每個事件都會經(jīng)過這個Layout 
  4.  

方法如上,把requestDisallowInterceptTouchEvent的實(shí)現(xiàn)干掉就可以了。

主要的技術(shù)點(diǎn)已近提出來了。那么下面就看具體實(shí)現(xiàn),首先看使用xml:

  1. <org.cgspine.nestscroll.one.EventDispatchPlanLayout 
  2.     android:id="@+id/scrollLayout" 
  3.     android:layout_marginTop="?attr/actionBarSize" 
  4.     android:layout_width="match_parent" 
  5.     android:layout_height="match_parent" 
  6.     app:header_view="@+id/book_header" 
  7.     app:target_view="@+id/scroll_view" 
  8.     app:header_init_offset="30dp" 
  9.     app:target_init_offset="70dp"
  10.     <View 
  11.         android:id="@id/book_header" 
  12.         android:layout_width="120dp" 
  13.         android:layout_height="150dp" 
  14.         android:background="@color/gray"/> 
  15.     <org.cgspine.nestscroll.one.EventDispatchTargetLayout 
  16.         android:id="@id/scroll_view" 
  17.         android:layout_width="match_parent" 
  18.         android:layout_height="match_parent" 
  19.         android:orientation="vertical" 
  20.         android:background="@color/white"
  21.         <android.support.design.widget.TabLayout 
  22.             android:id="@+id/tab_layout" 
  23.             android:background="@drawable/list_item_bg_with_border_top_bottom" 
  24.             android:layout_width="match_parent" 
  25.             android:layout_height="@dimen/tab_layout_height" 
  26.             android:fillViewport="true"/> 
  27.         <android.support.v4.view.ViewPager 
  28.             android:id="@+id/viewpager" 
  29.             android:layout_width="match_parent" 
  30.             android:layout_height="0dp" 
  31.             android:layout_weight="1"/> 
  32.     </org.cgspine.nestscroll.one.EventDispatchTargetLayout> 
  33. </org.cgspine.nestscroll.one.EventDispatchPlanLayout>  

EventDispatchTargetLayout實(shí)現(xiàn)了自定義接口ITargetView:

  1. public interface ITargetView { 
  2.     boolean canChildScrollUp(); 
  3.     void fling(float vy); 
  4.  

這是因?yàn)榕c具體業(yè)務(wù)抽離,我并不清楚內(nèi)層盒子是怎樣的(有可能就是ListView了,也有可能是ViewPager包裹ListView)

主要的實(shí)現(xiàn)在EventDispatchPlanLayout,使用時在xml中指定header_init_offset、target_init_offset等變量就可以了,基本上與業(yè)務(wù)邏輯獨(dú)立。

其重點(diǎn)實(shí)現(xiàn)邏輯在onInterceptTouchEvent與onTouchEvent中了。個人不是很建議去動dispatchTouchEvent,雖然所有事件都會經(jīng)過這里,但是這也明顯會增加代碼處理復(fù)雜度:

  1. public boolean onInterceptTouchEvent(MotionEvent ev) { 
  2.     ensureHeaderViewAndScrollView(); 
  3.     final int action = MotionEventCompat.getActionMasked(ev); 
  4.     int pointerIndex; 
  5.  
  6.     // 不阻斷事件的快路徑:如果目標(biāo)view可以往上滾動或者`EventDispatchPlanLayout`不是enabled 
  7.     if (!isEnabled() || mTarget.canChildScrollUp()) { 
  8.         Log.d(TAG, "fast end onIntercept: isEnabled = " + isEnabled() + "; canChildScrollUp = " 
  9.                 + mTarget.canChildScrollUp()); 
  10.         return false
  11.     } 
  12.     switch (action) { 
  13.         case MotionEvent.ACTION_DOWN: 
  14.             mActivePointerId = ev.getPointerId(0); 
  15.             mIsDragging = false
  16.             pointerIndex = ev.findPointerIndex(mActivePointerId); 
  17.             if (pointerIndex < 0) { 
  18.                 return false
  19.             } 
  20.             // 在down的時候記錄初始的y值 
  21.             mInitialDownY = ev.getY(pointerIndex); 
  22.             break; 
  23.  
  24.         case MotionEvent.ACTION_MOVE: 
  25.             pointerIndex = ev.findPointerIndex(mActivePointerId); 
  26.             if (pointerIndex < 0) { 
  27.                 Log.e(TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); 
  28.                 return false
  29.             } 
  30.  
  31.             final float y = ev.getY(pointerIndex); 
  32.             // 判斷是否dragging 
  33.             startDragging(y); 
  34.             break; 
  35.  
  36.         case MotionEventCompat.ACTION_POINTER_UP: 
  37.             // 雙指邏輯處理 
  38.             onSecondaryPointerUp(ev); 
  39.             break; 
  40.  
  41.         case MotionEvent.ACTION_UP: 
  42.         case MotionEvent.ACTION_CANCEL: 
  43.             mIsDragging = false
  44.             mActivePointerId = INVALID_POINTER; 
  45.             break; 
  46.     } 
  47.  
  48.     return mIsDragging; 
  49.  

代碼邏輯很清晰,應(yīng)該不用多說。接下來看onTouchEvent的處理邏輯。

  1. public boolean onTouchEvent(MotionEvent ev) { 
  2.     final int action = MotionEventCompat.getActionMasked(ev); 
  3.     int pointerIndex; 
  4.  
  5.     if (!isEnabled() || mTarget.canChildScrollUp()) { 
  6.         Log.d(TAG, "fast end onTouchEvent: isEnabled = " + isEnabled() + "; canChildScrollUp = " 
  7.                 + mTarget.canChildScrollUp()); 
  8.         return false
  9.     } 
  10.    // 速度追蹤 
  11.    acquireVelocityTracker(ev); 
  12.  
  13.     switch (action) { 
  14.         case MotionEvent.ACTION_DOWN: 
  15.             mActivePointerId = ev.getPointerId(0); 
  16.             mIsDragging = false
  17.             break; 
  18.  
  19.         case MotionEvent.ACTION_MOVE: { 
  20.             pointerIndex = ev.findPointerIndex(mActivePointerId); 
  21.             if (pointerIndex < 0) { 
  22.                 Log.e(TAG, "Got ACTION_MOVE event but have an invalid active pointer id."); 
  23.                 return false
  24.             } 
  25.             final float y = ev.getY(pointerIndex); 
  26.             startDragging(y); 
  27.  
  28.             if (mIsDragging) { 
  29.                 float dy = y - mLastMotionY; 
  30.                 if (dy >= 0) { 
  31.                     moveTargetView(dy); 
  32.                 } else { 
  33.                     if (mTargetCurrentOffset + dy <= mTargetEndOffset) { 
  34.                         moveTargetView(dy); 
  35.                         // 重新dispatch一次down事件,使得列表可以繼續(xù)滾動 
  36.                         int oldAction = ev.getAction(); 
  37.                         ev.setAction(MotionEvent.ACTION_DOWN); 
  38.                         dispatchTouchEvent(ev); 
  39.                         ev.setAction(oldAction); 
  40.                     } else { 
  41.                         moveTargetView(dy); 
  42.                     } 
  43.                 } 
  44.                 mLastMotionY = y; 
  45.             } 
  46.             break; 
  47.         } 
  48.         case MotionEventCompat.ACTION_POINTER_DOWN: { 
  49.             pointerIndex = MotionEventCompat.getActionIndex(ev); 
  50.             if (pointerIndex < 0) { 
  51.                 Log.e(TAG, "Got ACTION_POINTER_DOWN event but have an invalid action index."); 
  52.                 return false
  53.             } 
  54.             mActivePointerId = ev.getPointerId(pointerIndex); 
  55.             break; 
  56.         } 
  57.  
  58.         case MotionEventCompat.ACTION_POINTER_UP: 
  59.             onSecondaryPointerUp(ev); 
  60.             break; 
  61.  
  62.         case MotionEvent.ACTION_UP: { 
  63.             pointerIndex = ev.findPointerIndex(mActivePointerId); 
  64.             if (pointerIndex < 0) { 
  65.                 Log.e(TAG, "Got ACTION_UP event but don't have an active pointer id."); 
  66.                 return false
  67.             } 
  68.  
  69.             if (mIsDragging) { 
  70.                 mIsDragging = false
  71.                 // 獲取瞬時速度 
  72.                 mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity); 
  73.                 final float vy = mVelocityTracker.getYVelocity(mActivePointerId); 
  74.                 finishDrag((int) vy); 
  75.             } 
  76.             mActivePointerId = INVALID_POINTER; 
  77.             //釋放速度追蹤 
  78.             releaseVelocityTracker(); 
  79.             return false
  80.         } 
  81.         case MotionEvent.ACTION_CANCEL: 
  82.             releaseVelocityTracker(); 
  83.             return false
  84.     } 
  85.  
  86.     return mIsDragging; 
  87.  

或許有人會說:為何與onInterceptTouchEvent與有很多重復(fù)代碼?這是因?yàn)槿绻录淮驍?,并且子類不處理,就會走進(jìn)onTouchEvent邏輯,所以這些重復(fù)處理是有意義的(其實(shí)是抄SwipeRefreshLayout的)。里面主要的邏輯就是兩個:

  1. 滾動容器
  2. TouchUp時滾動到特定位置以及fling傳遞

滾動容器的邏輯: 

  1. private void moveTargetViewTo(int target) { 
  2.     target = Math.max(target, mTargetEndOffset); 
  3.     // 用offsetTopAndBottom來偏移view 
  4.     ViewCompat.offsetTopAndBottom(mTargetView, target - mTargetCurrentOffset); 
  5.     mTargetCurrentOffset = target; 
  6.  
  7.     // 滾動書籍封面view,根據(jù)TargetView進(jìn)行定位 
  8.     int headerTarget; 
  9.     if (mTargetCurrentOffset >= mTargetInitOffset) { 
  10.         headerTarget = mHeaderInitOffset; 
  11.     } else if (mTargetCurrentOffset <= mTargetEndOffset) { 
  12.         headerTarget = mHeaderEndOffset; 
  13.     } else { 
  14.         float percent = (mTargetCurrentOffset - mTargetEndOffset) * 1.0f / mTargetInitOffset - mTargetEndOffset; 
  15.         headerTarget = (int) (mHeaderEndOffset + percent * (mHeaderInitOffset - mHeaderEndOffset)); 
  16.     } 
  17.     ViewCompat.offsetTopAndBottom(mHeaderView, headerTarget - mHeaderCurrentOffset); 
  18.     mHeaderCurrentOffset = headerTarget; 
  19.  

TouchUp的滾動邏輯:

  1. private void finishDrag(int vy) { 
  2.     Log.i(TAG, "TouchUp: vy = " + vy); 
  3.     if (vy > 0) { 
  4.         // 向下觸發(fā)fling,需要滾動到Init位置 
  5.         mNeedScrollToInitPos = true
  6.         mScroller.fling(0, mTargetCurrentOffset, 0, vy, 
  7.                 0, 0, mTargetEndOffset, Integer.MAX_VALUE); 
  8.         invalidate(); 
  9.     } else if (vy < 0) { 
  10.        // 向上觸發(fā)fling,需要滾動到End位置 
  11.         mNeedScrollToEndPos = true
  12.         mScroller.fling(0, mTargetCurrentOffset, 0, vy, 
  13.                 0, 0, mTargetEndOffset, Integer.MAX_VALUE); 
  14.         invalidate(); 
  15.     } else { 
  16.         // 沒有觸發(fā)fling,就近原則 
  17.         if (mTargetCurrentOffset <= (mTargetEndOffset + mTargetInitOffset) / 2) { 
  18.             mNeedScrollToEndPos = true
  19.         } else { 
  20.             mNeedScrollToInitPos = true
  21.         } 
  22.         invalidate(); 
  23.     } 
  24.  

當(dāng)然這里會打上一些標(biāo)志位,具體實(shí)現(xiàn)是在computeScroll中,這屬于Scroller的功能,這里就不展開了。

這樣大體邏輯就講述清楚了,其它細(xì)節(jié)就請看官直接看源碼了。

基于NestingScroll機(jī)制的實(shí)現(xiàn)方案

NestingScroll機(jī)制是在某個版本support包加入的,不過外界極少有文章介紹,所以應(yīng)該大多數(shù)人并不知道這個機(jī)制。NestingScroll主要有兩個接口:

  • NestedScrollingParent
  • NestedScrollingChild

當(dāng)我們需要使用NestingScroll特性時,我們?nèi)?shí)現(xiàn)這兩個接口就好了。NestingScroll本質(zhì)是內(nèi)部攔截發(fā)然后將相應(yīng)的接口開給外界。因此實(shí)現(xiàn)NestedScrollingChild接口是有難度的,不過像RecyclerView這些控件,官方已經(jīng)幫我們實(shí)現(xiàn)好了NestedScrollingChild,要完成我們的需求,我們直接拿來用就好了(ListView就沒辦法使用了,當(dāng)然你也可以去實(shí)現(xiàn)NestedScrollingChild接口)。并且NestedScrollingChild與NestedScrollingParent只要有嵌套關(guān)系就行了,并不一定NestedScrollingChild是直接的子View。

我們來來看看NestedScrollingParent的定義:

  1. public interface NestedScrollingParent { 
  2.     // 是否接受NestingScroll 
  3.     public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes); 
  4.     // 接受NestingScroll的Hook鉤子 
  5.     public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes); 
  6.     // NestingScroll結(jié)束 
  7.     public void onStopNestedScroll(View target); 
  8.     // NestingScroll進(jìn)行中。重要參數(shù)dxUnconsumed, dyUnconsumed: 用于表示沒有被消耗的滾動量,一般是列表滾動到頭了,就會產(chǎn)生未消耗量 
  9.     public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed); 
  10.     // NestingScroll滾動之前。重要參數(shù)consumed: 是用于告訴子View我消耗了多少。如果位全部消耗dy,那么子view就可以消耗了。 
  11.     public void onNestedPreScroll(View target, int dx, int dy, int[] consumed); 
  12.     // fling時 
  13.     public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed); 
  14.     // fling之前:可以由父元素消耗這次fling事件 
  15.     public boolean onNestedPreFling(View target, float velocityX, float velocityY); 
  16.    // 獲取滾動軸: x軸或y軸 
  17.    public int getNestedScrollAxes(); 
  18.  

接口是非常豐富的。有一個很重要的概念:消耗量。 比如我滑動了10dp,那么父元素先看看可以消耗多少(例如4dp),然后會把未消耗量傳遞給子View(6dp)。這就把嵌套滾動的問題轉(zhuǎn)換為資源分配的問題了。非常機(jī)智。除此以外,官方提供了NestedScrollingParentHelper類幫我實(shí)現(xiàn)了一些公共方法并做好了低版本兼容,我們應(yīng)當(dāng)拿來用。

寫在***

雖然google提供了很多新穎好玩的接口。但這需要花費(fèi)部分精力去實(shí)踐這些新技術(shù)。這是非常有意義的投入。多看、多寫,才能幫助我們用更少的時間寫更好的代碼。 

責(zé)任編輯:龐桂玉 來源: Android開發(fā)中文站
相關(guān)推薦

2010-03-02 13:38:30

Android命令

2011-09-15 09:50:33

2013-05-17 13:47:25

Android開發(fā)ScrollViewGridView

2017-01-04 18:29:20

AndroidNestedScrol嵌套滑動機(jī)制

2014-10-15 14:07:21

AndroidGlide組件

2013-07-10 10:21:22

Android Lis

2013-01-05 17:45:11

Android開發(fā)特效滾動屏幕

2010-10-19 11:14:06

2010-03-03 17:19:48

Android

2011-09-02 10:14:10

JQuery滾動Xslider

2020-07-22 08:49:43

加密

2023-10-10 09:07:23

2010-08-26 11:15:47

LinuxICMP后門

2010-09-06 14:32:55

CISCO PPP配置

2009-11-17 09:32:32

PHP數(shù)值函數(shù)

2019-05-13 09:11:41

加密解密Python攻擊

2024-02-21 20:10:18

滾動視頻網(wǎng)頁

2018-05-12 16:26:17

互聯(lián)網(wǎng)VPC子網(wǎng)

2024-04-09 12:08:51

Next組件Next.js

2011-08-10 15:58:12

WPS符號欄
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

91免费版网站在线观看| 在线视频亚洲欧美| 日b视频免费观看| 搡老岳熟女国产熟妇| 先锋影音久久| 日韩中文字幕国产| 日本中文字幕精品| 亚洲天堂资源| 国产精品福利一区二区三区| 亚洲综合av影视| 日韩熟女精品一区二区三区| 精品久久久久久久久久久下田| 在线不卡中文字幕| 日韩精品―中文字幕| 永久免费av片在线观看全网站| 国产精品123| 国产精品第七影院| 精品少妇爆乳无码av无码专区| 国产精品嫩草影院在线看| 5858s免费视频成人| 国产原创中文在线观看 | 中国黄色录像片| 性xxxx搡xxxxx搡欧美| 极品少妇xxxx精品少妇偷拍| 4438全国亚洲精品在线观看视频| av黄色免费在线观看| 中文有码一区| 日韩免费一区二区三区在线播放| 国产天堂在线播放| 51精品在线| 亚洲欧美日韩电影| 日韩精品欧美专区| 亚州精品国产精品乱码不99按摩| 国产精品伊人色| 国产精品精品国产| 欧美日韩综合在线观看| 欧美日韩调教| 美女少妇精品视频| 国产传媒免费在线观看| 少妇一区二区视频| 日韩精品www| a级一a一级在线观看| 日本一区二区三区播放| 欧美日韩国产bt| 不卡的av中文字幕| 亚洲精品国产嫩草在线观看| 偷拍一区二区三区| 国产曰肥老太婆无遮挡| av免费在线观看网址| 中文字幕亚洲一区二区va在线| 日韩av高清| 国产区在线视频| 国产亚洲精品7777| 欧美日韩在线一二三| 日本大片在线观看| 久久婷婷国产综合国色天香| 久久国产精品精品国产色婷婷| 日本黄色三级视频| 成人av高清在线| 国产精品区一区二区三在线播放 | 天堂av在线| 欧美日韩在线免费观看| 一女被多男玩喷潮视频| 精品极品在线| 欧美日韩一区二区精品| 人妻无码视频一区二区三区| 日韩免费小视频| 欧美亚洲图片小说| www.色欧美| 免费观看性欧美大片无片| 日韩一区二区在线播放| 久久久久久久久久久久国产精品| 国产乱人伦丫前精品视频| 亚洲成色777777女色窝| 亚洲成人日韩在线| 精品国产乱码久久久久久果冻传媒 | 色愁久久久久久| 亚洲人成电影在线| 超碰人人人人人人人| 91成人精品视频| 欧美激情性做爰免费视频| 日韩乱码一区二区| 玖玖国产精品视频| 91精品久久久久久| 免费av网站在线播放| 久久久国产精品不卡| 在线看成人av电影| 2021天堂中文幕一二区在线观| 欧美性猛交xxxx乱大交3| 国产精品拍拍拍| 欧美区一区二区| 日韩av在线网页| 国产又粗又硬视频| 欧美日本一区| 欧美在线免费看| 国产精品久久影视| jizz一区二区| 亚洲精品免费在线看| 污污的网站在线看| 日本大香伊一区二区三区| 激情图片中文字幕| 日韩av不卡一区| 俺去啦;欧美日韩| 国产又爽又黄的视频| 久久99在线观看| 精品国产一二| 国产素人视频在线观看| 狠狠躁天天躁日日躁欧美| 不卡的在线视频| 亚洲va久久| 九九热这里只有精品6| av毛片在线免费观看| 国产精一品亚洲二区在线视频| 久久天天狠狠| 69成人在线| 欧美在线视频日韩| 久久福利小视频| 一区二区在线影院| 国产精品劲爆视频| 色吊丝在线永久观看最新版本| 亚洲欧美日韩一区二区| 免费黄色特级片| 国偷自产av一区二区三区| 色噜噜狠狠狠综合曰曰曰| 日本午夜视频在线观看| 国内欧美视频一区二区| 日本公妇乱淫免费视频一区三区| 成年人黄色大片在线| 欧美日韩中文国产| 精品无码一区二区三区| 99视频一区| 国产精品.com| av免费在线观| 欧美一区二区三区啪啪| 国产又粗又长免费视频| 日韩国产在线一| 欧美另类视频在线| 美女的胸无遮挡在线观看| 精品国产第一区二区三区观看体验| 国产美女久久久久久| 日本欧美一区二区| 日本高清不卡一区二区三| 中文字幕人成乱码在线观看| 精品成人一区二区三区四区| 欧美成人一二三区| 国产老女人精品毛片久久| 性生活免费观看视频| 成人污版视频| 久久五月天色综合| 国产情侣在线播放| 中文字幕一区二区在线播放| 97超碰成人在线| 久久国产中文字幕| 国产中文字幕91| 婷婷在线视频观看| 欧美日韩国产综合一区二区三区| 色屁屁草草影院ccyy.com| 日韩精品一二三四| 午夜视频久久久| 日韩三级成人| 欧美成人免费网| а√中文在线资源库| 伊人一区二区三区| 亚洲精品无码一区二区| 亚洲免费高清| 欧美日韩精品久久| 99re66热这里只有精品4| 中文字幕国产精品久久| 国产又粗又大又爽视频| 一区二区三区不卡视频在线观看| 一区二区在线免费观看视频| 在线播放一区| 老牛影视免费一区二区| 欧美人与性动交xxⅹxx| 中文字幕在线成人| 不卡视频免费在线观看| 欧美日韩精品在线视频| 国产一区二区三区四区在线| 韩国视频一区二区| 丰满的少妇愉情hd高清果冻传媒| 亚洲a级精品| 国产日韩在线免费| 中文在线免费| 日韩经典中文字幕| 亚洲天堂中文字幕在线| 一二三四社区欧美黄| 真人bbbbbbbbb毛片| 美美哒免费高清在线观看视频一区二区| 亚洲一区不卡在线| 一本色道69色精品综合久久| 欧美亚洲另类激情另类| 日本成人网址| 亚洲精品久久久久| 中文字幕人妻丝袜乱一区三区| 一区二区高清在线| 精品成人av一区二区三区| 国产呦精品一区二区三区网站| 精品少妇人妻av免费久久洗澡| 日韩欧美视频在线播放| 国产伦精品一区二区三| julia一区二区三区中文字幕| 欧美激情a在线| 国产高清美女一级毛片久久| 日韩亚洲欧美一区| 波多野结衣激情视频| 亚洲一级片在线观看| 无码人妻丰满熟妇啪啪欧美| 成人av网站免费| 一级做a免费视频| 免费日韩av片| 青春草国产视频| 色琪琪久久se色| 久久青青草原一区二区| 亚洲**毛片| 国产精品自在线| 在线成人av观看| 色综合久久久888| 日本激情在线观看| 亚洲美女视频网| 人妻va精品va欧美va| 欧美精品粉嫩高潮一区二区| 精品国产xxx| 亚洲1区2区3区视频| 国产免费久久久久| 欧美激情在线看| asian性开放少妇pics| 国产精品18久久久久久vr| 亚洲精品第三页| 免费欧美在线视频| 国产裸体舞一区二区三区| 在线视频观看日韩| 黄色三级中文字幕| 香蕉精品视频在线观看| 亚洲黄色一区二区三区| 狠狠色丁香婷婷综合影院| 精品国产一区二区三区免费| 91综合精品国产丝袜长腿久久| 91久久久久久| 欧美一级免费| 国产这里只有精品| 祥仔av免费一区二区三区四区| 日韩免费在线看| 中文字幕色婷婷在线视频| 51色欧美片视频在线观看| 成年男女免费视频网站不卡| 久久久久久久久久婷婷| 久草在线资源站资源站| 欧美激情精品久久久久久大尺度 | 韩国一区二区av| 国产精品久久国产愉拍| 每日在线更新av| 亚洲综合好骚| 激情综合网婷婷| 日韩经典中文字幕一区| 无码日韩人妻精品久久蜜桃| 日韩和欧美一区二区| www.亚洲高清| 韩日av一区二区| 91porn在线| 不卡欧美aaaaa| 青青草视频成人| 国产日韩欧美精品一区| 国产精品情侣呻吟对白视频| 国产精品福利一区二区三区| 欧美成人黄色网| 亚洲午夜私人影院| 一区二区三区福利视频| 一本色道久久综合亚洲91 | 日韩一区二区高清| 亚洲国产成人精品一区二区三区| 亚洲国产精彩中文乱码av在线播放| 天堂网在线中文| 亚洲午夜未删减在线观看| 自拍视频在线| 欧美黑人视频一区| 英国三级经典在线观看| 国产精品视频99| 亚洲91网站| 欧美日韩精品综合| 国产电影一区二区在线观看| 日本一级黄视频| 亚洲综合精品| 亚洲精品在线网址| a级精品国产片在线观看| 国产视频三区四区| 一区二区视频在线看| 一区二区三区在线观看av| 欧美日韩国产首页| 国产综合无码一区二区色蜜蜜| 亚洲精品天天看| 美女黄视频在线观看| 久久久噜噜噜久久中文字免| 第四色男人最爱上成人网| 2014亚洲精品| 精品国产乱码久久久| 91免费国产精品| 天堂在线亚洲视频| 中文字幕乱妇无码av在线| 久久久久久久久久久久久久久99 | 亚洲无中文字幕| 丰满爆乳一区二区三区| 久久精品国产99久久6| 午夜免费福利影院| 国产精品毛片高清在线完整版| 久久国产精品波多野结衣av | 136福利视频导航| 亚洲第一精品福利| 日本韩国在线视频爽| 97精品视频在线播放| 日韩美女在线| 欧美一区二区三区四区在线观看地址 | 国产麻豆成人精品| 舐め犯し波多野结衣在线观看| 亚洲精品第一国产综合野| 日韩精品在线一区二区三区| 亚洲福利视频久久| 国产二区三区在线| 国产精品露脸自拍| 窝窝社区一区二区| www.xxx麻豆| 极品美女销魂一区二区三区免费| 国产美女喷水视频| 亚洲国产欧美在线| 国产免费视频一区二区三区| 亚洲图片欧洲图片av| 蜜桃视频m3u8在线观看| 成人女人免费毛片| 国产精品成人av| 日本888xxxx| 久久久777精品电影网影网| 精品成人久久久| 精品国产123| 国内高清免费在线视频| 成人午夜高潮视频| 外国成人免费视频| 亚洲欧美在线精品| 中文字幕乱码亚洲精品一区| 丁香六月婷婷综合| 日韩精品免费综合视频在线播放| 草美女在线观看| 国产高清在线一区| 亚洲天堂久久| 成人在线电影网站| 亚洲成人你懂的| 六月婷婷综合网| 欧美激情xxxx性bbbb| 日本精品在线播放 | 美女网站视频在线| 亚洲va欧美va国产综合久久| 国产精品久久久久久| 亚洲精品久久久久久宅男| 国产精品免费人成网站| 在线观看亚洲国产| 精品久久久av| 99视频有精品高清视频| 黄色一级视频播放| 国产.欧美.日韩| 天海翼一区二区| 精品一区电影国产| 日韩一区二区三区在线免费观看 | 亚洲蜜桃视频| 成人做爰69片免费| 亚洲不卡在线观看| 日韩精品系列| 国产精品国产福利国产秒拍| 日韩毛片视频| 污视频在线观看免费网站| 一区二区三区欧美久久| 黄色片一区二区| 欧美中文在线免费| 日韩大片在线观看| 992kp免费看片| 亚洲午夜免费电影| 女人天堂在线| 91精品国产综合久久香蕉922| 欧美日韩1区2区3区| 挪威xxxx性hd极品| 日韩欧美在线中文字幕| 日本在线视频观看| 国产精品久久亚洲7777| 天堂精品中文字幕在线| 国产一区二区三区视频播放| 欧美一区二区三区视频在线观看| 日本大片在线播放| 欧美日韩综合久久| 狠狠色丁香久久婷婷综合_中| 国产亚洲欧美精品久久久www| 日韩成人免费视频| 日韩欧美三区| www.爱色av.com| 中文字幕一区二区三| 人妻精品无码一区二区| 国产精品天天狠天天看| 亚洲精品专区| 精品一区二区6| 精品福利二区三区| 欧美大陆国产| 日韩少妇内射免费播放18禁裸乳| 中文字幕在线不卡视频| 天天干天天爱天天操|