亚洲第一综合天堂另类专_亚洲AV综合天堂在线观看_亚洲va成无码人在线观看天堂_亚洲A∨无码精品午夜电影香港_亚洲av日韩av无码a一区_亚洲av无码不卡私人影院

轉(zhuǎn)載請注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/21696315),請尊重他人的辛勤勞動成果,謝謝!

今 天這篇文章主要分析的是Android的事件分發(fā)機制,采用例子加源碼的方式讓大家深刻的理解Android事件分發(fā)的具體情況,雖然網(wǎng)上很多 Android的事件分發(fā)的文章,有些還寫的不錯,但是我還是決定寫這篇文章,用我自己的思維方式來幫助大家理解Android事件分發(fā),Android 事件分發(fā)到底有多重要呢?相信很多Android開發(fā)者都明白吧,這個我就不介紹了,我也寫了很多篇文章里面涉及到Android的事件處理的問題,可能 不理解Android事件分發(fā)的朋友會有點難理解吧,不過沒關(guān)系,相信看了這篇文章的你會對Android事件分發(fā)有進一步的理解。我這篇文章分析的源碼 是Android 2.2的源碼, 也許你會說,干嘛不去分析最新的源碼呢?我這里要解釋一下,Android 2.2的源碼跟最新的源碼在功能效果方面是一樣的,只不過最新的源碼相對于Android 2.2來說更加健壯一些, Android 2.2的事件處理的代碼幾乎都寫在一個方法體里面,而最新的源碼分了很多個方法寫,如果用最新的源碼調(diào)用方法會繞來繞去的,相信你看的也會暈,出于這個考 慮,我就拿Android 2.2的源碼來給大家分析。

 

ViewGroup的事件分發(fā)機制

我 們用手指去觸摸Android手機屏幕,就會產(chǎn)生一個觸摸事件,但是這個觸摸事件在底層是怎么分發(fā)的呢?這個我還真不知道,這里涉及到操作硬件(手機屏 幕)方面的知識,也就是Linux內(nèi)核方面的知識,我也沒有了解過這方面的東西,所以我們可能就往上層來分析分析,我們知道Android中負責與用戶交 互,與用戶操作緊密相關(guān)的四大組件之一是Activity, 所以我們有理由相信Activity中存在分發(fā)事件的方法,這個方法就是dispatchTouchEvent(),我們先看其源碼吧

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public boolean dispatchTouchEvent(MotionEvent ev) {  

  2.   

  3.         //如果是按下狀態(tài)就調(diào)用onUserInteraction()方法,onUserInteraction()方法  

  4.         //是個空的方法, 我們直接跳過這里看下面的實現(xiàn)  

  5.         if (ev.getAction() == MotionEvent.ACTION_DOWN) {  

  6.             onUserInteraction();  

  7.         }  

  8.           

  9.         if (getWindow().superDispatchTouchEvent(ev)) {  

  10.             return true;  

  11.         }  

  12.           

  13.         //getWindow().superDispatchTouchEvent(ev)返回false,這個事件就交給Activity  

  14.         //來處理, Activity的onTouchEvent()方法直接返回了false  

  15.         return onTouchEvent(ev);  

  16.     }  

這 個方法中我們還是比較關(guān)心getWindow()的superDispatchTouchEvent()方法,getWindow()返回當前 Activity的頂層窗口Window對象,我們直接看Window API的superDispatchTouchEvent()方法

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. /**

  2.      * Used by custom windows, such as Dialog, to pass the touch screen event

  3.      * further down the view hierarchy. Application developers should

  4.      * not need to implement or call this.

  5.      *

  6.      */  

  7.     public abstract boolean superDispatchTouchEvent(MotionEvent event);  

這個是個抽象方法,所以我們直接找到其子類來看看superDispatchTouchEvent()方法的具體邏輯實現(xiàn),Window的唯一子類是PhoneWindow,我們就看看PhoneWindow的superDispatchTouchEvent()方法

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public boolean superDispatchTouchEvent(KeyEvent event) {  

  2.         return mDecor.superDispatcTouchEvent(event);  

  3.     }  

里 面直接調(diào)用DecorView類的superDispatchTouchEvent()方法,或許很多人不了解DecorView這個 類,DecorView是PhoneWindow的一個final的內(nèi)部類并且繼承FrameLayout的,也是Window界面的最頂層的View對 象,這是什么意思呢?別著急,我們接著往下看
我們先新建一個項目,取名AndroidTouchEvent,然后直接用模擬器運行項目, MainActivity的布局文件為

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  

  2.     xmlns:tools="http://schemas.android.com/tools"  

  3.     android:layout_width="match_parent"  

  4.     android:layout_height="match_parent"  

  5.     tools:context=".MainActivity" >  

  6.   

  7.     <TextView  

  8.         android:layout_width="wrap_content"  

  9.         android:layout_height="wrap_content"  

  10.         android:layout_centerHorizontal="true"  

  11.         android:layout_centerVertical="true"  

  12.         android:text="@string/hello_world" />  

  13.   

  14. RelativeLayout>  

利用hierarchyviewer工具來查看下MainActivity的View的層次結(jié)構(gòu),如下圖



我們看到最頂層就是PhoneWindow$DecorView,接著DecorView下面有一個LinearLayout, LinearLayout下面有兩個FrameLayout

上 面那個FrameLayout是用來顯示標題欄的,這個Demo中是一個TextView,當然我們還可以定制我們的標題欄,利用 getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.XXX); xxx就是我們自定義標題欄的布局XML文件
下面的FrameLayout是用來裝載ContentView的,也就是我們在Activity中 利用setContentView()方法設置的View,現(xiàn)在我們知道了,原來我們利用setContentView()設置Activity的 View的外面還嵌套了這么多的東西

我們來理清下思路,Activity的最頂層窗體是PhoneWindow,而PhoneWindow的最頂層View是DecorView,接下來我們就看DecorView類的superDispatchTouchEvent()方法

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public boolean superDispatchTouchEvent(MotionEvent event) {  

  2.             return super.dispatchTouchEvent(event);  

  3.         }  

在里面調(diào)用了父類FrameLayout的dispatchTouchEvent()方法,而FrameLayout中并沒有dispatchTouchEvent()方法,所以我們直接看ViewGroup的dispatchTouchEvent()方法

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. /**

  2.     * {@inheritDoc}

  3.     */  

  4.    @Override  

  5.    public boolean dispatchTouchEvent(MotionEvent ev) {  

  6.        final int action = ev.getAction();  

  7.        final float xf = ev.getX();  

  8.        final float yf = ev.getY();  

  9.        final float scrolledXFloat = xf + mScrollX;  

  10.        final float scrolledYFloat = yf + mScrollY;  

  11.        final Rect frame = mTempRect;  

  12.   

  13.        //這個值默認是false, 然后我們可以通過requestDisallowInterceptTouchEvent(boolean disallowIntercept)方法  

  14.        //來改變disallowIntercept的值  

  15.        boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;  

  16.   

  17.        //這里是ACTION_DOWN的處理邏輯  

  18.        if (action == MotionEvent.ACTION_DOWN) {  

  19.         //清除mMotionTarget, 每次ACTION_DOWN都很設置mMotionTarget為null  

  20.            if (mMotionTarget != null) {  

  21.                mMotionTarget = null;  

  22.            }  

  23.   

  24.            //disallowIntercept默認是false, 就看ViewGroup的onInterceptTouchEvent()方法  

  25.            if (disallowIntercept || !onInterceptTouchEvent(ev)) {  

  26.                ev.setAction(MotionEvent.ACTION_DOWN);  

  27.                final int scrolledXInt = (int) scrolledXFloat;  

  28.                final int scrolledYInt = (int) scrolledYFloat;  

  29.                final View[] children = mChildren;  

  30.                final int count = mChildrenCount;  

  31.                //遍歷其子View  

  32.                for (int i = count - 1; i >= 0; i--) {  

  33.                    final View child = children[i];  

  34.                      

  35.                    //如果該子View是VISIBLE或者該子View正在執(zhí)行動畫, 表示該View才  

  36.                    //可以接受到Touch事件  

  37.                    if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE  

  38.                            || child.getAnimation() != null) {  

  39.                     //獲取子View的位置范圍  

  40.                        child.getHitRect(frame);  

  41.                          

  42.                        //如Touch到屏幕上的點在該子View上面  

  43.                        if (frame.contains(scrolledXInt, scrolledYInt)) {  

  44.                            // offset the event to the view's coordinate system  

  45.                            final float xc = scrolledXFloat - child.mLeft;  

  46.                            final float yc = scrolledYFloat - child.mTop;  

  47.                            ev.setLocation(xc, yc);  

  48.                            child.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;  

  49.                              

  50.                            //調(diào)用該子View的dispatchTouchEvent()方法  

  51.                            if (child.dispatchTouchEvent(ev))  {  

  52.                                // 如果child.dispatchTouchEvent(ev)返回true表示  

  53.                             //該事件被消費了,設置mMotionTarget為該子View  

  54.                                mMotionTarget = child;  

  55.                                //直接返回true  

  56.                                return true;  

  57.                            }  

  58.                            // The event didn't get handled, try the next view.  

  59.                            // Don't reset the event's location, it's not  

  60.                            // necessary here.  

  61.                        }  

  62.                    }  

  63.                }  

  64.            }  

  65.        }  

  66.   

  67.        //判斷是否為ACTION_UP或者ACTION_CANCEL  

  68.        boolean isUpOrCancel = (action == MotionEvent.ACTION_UP) ||  

  69.                (action == MotionEvent.ACTION_CANCEL);  

  70.   

  71.        if (isUpOrCancel) {  

  72.            //如果是ACTION_UP或者ACTION_CANCEL, 將disallowIntercept設置為默認的false  

  73.         //假如我們調(diào)用了requestDisallowInterceptTouchEvent()方法來設置disallowIntercept為true  

  74.         //當我們抬起手指或者取消Touch事件的時候要將disallowIntercept重置為false  

  75.         //所以說上面的disallowIntercept默認在我們每次ACTION_DOWN的時候都是false  

  76.            mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;  

  77.        }  

  78.   

  79.        // The event wasn't an ACTION_DOWN, dispatch it to our target if  

  80.        // we have one.  

  81.        final View target = mMotionTarget;  

  82.        //mMotionTarget為null意味著沒有找到消費Touch事件的View, 所以我們需要調(diào)用ViewGroup父類的  

  83.        //dispatchTouchEvent()方法,也就是View的dispatchTouchEvent()方法  

  84.        if (target == null) {  

  85.            // We don't have a target, this means we're handling the  

  86.            // event as a regular view.  

  87.            ev.setLocation(xf, yf);  

  88.            if ((mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) {  

  89.                ev.setAction(MotionEvent.ACTION_CANCEL);  

  90.                mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;  

  91.            }  

  92.            return super.dispatchTouchEvent(ev);  

  93.        }  

  94.   

  95.        //這個if里面的代碼ACTION_DOWN不會執(zhí)行,只有ACTION_MOVE  

  96.        //ACTION_UP才會走到這里, 假如在ACTION_MOVE或者ACTION_UP攔截的  

  97.        //Touch事件, 將ACTION_CANCEL派發(fā)給target,然后直接返回true  

  98.        //表示消費了此Touch事件  

  99.        if (!disallowIntercept && onInterceptTouchEvent(ev)) {  

  100.            final float xc = scrolledXFloat - (float) target.mLeft;  

  101.            final float yc = scrolledYFloat - (float) target.mTop;  

  102.            mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;  

  103.            ev.setAction(MotionEvent.ACTION_CANCEL);  

  104.            ev.setLocation(xc, yc);  

  105.              

  106.            if (!target.dispatchTouchEvent(ev)) {  

  107.            }  

  108.            // clear the target  

  109.            mMotionTarget = null;  

  110.            // Don't dispatch this event to our own view, because we already  

  111.            // saw it when intercepting; we just want to give the following  

  112.            // event to the normal onTouchEvent().  

  113.            return true;  

  114.        }  

  115.   

  116.        if (isUpOrCancel) {  

  117.            mMotionTarget = null;  

  118.        }  

  119.   

  120.        // finally offset the event to the target's coordinate system and  

  121.        // dispatch the event.  

  122.        final float xc = scrolledXFloat - (float) target.mLeft;  

  123.        final float yc = scrolledYFloat - (float) target.mTop;  

  124.        ev.setLocation(xc, yc);  

  125.   

  126.        if ((target.mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) {  

  127.            ev.setAction(MotionEvent.ACTION_CANCEL);  

  128.            target.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;  

  129.            mMotionTarget = null;  

  130.        }  

  131.   

  132.        //如果沒有攔截ACTION_MOVE, ACTION_DOWN的話,直接將Touch事件派發(fā)給target  

  133.        return target.dispatchTouchEvent(ev);  

  134.    }  

這個方法相對來說還是蠻長,不過所有的邏輯都寫在一起,看起來比較方便,接下來我們就具體來分析一下

 

我們點擊屏幕上面的TextView來看看Touch是如何分發(fā)的,先看看ACTION_DOWN

在 DecorView這一層會直接調(diào)用ViewGroup的dispatchTouchEvent(), 先看18行,每次ACTION_DOWN都會將mMotionTarget設置為null, mMotionTarget是什么?我們先不管,繼續(xù)看代 碼,走到25行,  disallowIntercept默認為false,我們再看ViewGroup的onInterceptTouchEvent()方法

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public boolean onInterceptTouchEvent(MotionEvent ev) {  

  2.       return false;  

  3.   }  

直 接返回false, 繼續(xù)往下看,循環(huán)遍歷DecorView里面的Child,從上面的MainActivity的層次結(jié)構(gòu)圖我們可以看出,DecorView里面只有一個 Child那就是LinearLayout, 第43行判斷Touch的位置在不在LinnearLayout上面,這是毫無疑問的,所以直接跳到51行, 調(diào)用LinearLayout的dispatchTouchEvent()方法,LinearLayout也沒有 dispatchTouchEvent()這個方法,所以也是調(diào)用ViewGroup的dispatchTouchEvent()方法,所以這個方法卡在 51行沒有繼續(xù)下去,而是去先執(zhí)行LinearLayout的dispatchTouchEvent()

LinearLayout 調(diào)用dispatchTouchEvent()的邏輯跟DecorView是一樣的,所以也是遍歷LinearLayout的兩個 FrameLayout,判斷Touch的是哪個FrameLayout,很明顯是下面那個,調(diào)用下面那個FrameLayout的 dispatchTouchEvent(),  所以LinearLayout的dispatchTouchEvent()卡在51也沒繼續(xù)下去

繼 續(xù)調(diào)用FrameLayout的dispatchTouchEvent()方法,和上面一樣的邏輯,下面的FrameLayout也只有一個Child, 就是RelativeLayout,F(xiàn)rameLayout的dispatchTouchEvent()繼續(xù)卡在51行,先執(zhí)行 RelativeLayout的dispatchTouchEvent()方法

執(zhí)行RelativeLayout的 dispatchTouchEvent()方法邏輯還是一樣的,循環(huán)遍歷 RelativeLayout里面的孩子,里面只有一個TextView, 所以這里就調(diào)用TextView的dispatchTouchEvent(), TextView并沒有dispatchTouchEvent()這個方法,于是找TextView的父類View,在看View的 dispatchTouchEvent()的方法之前,我們先理清下上面這些ViewGroup執(zhí)行dispatchTouchEvent()的思路,我 畫了一張圖幫大家理清下(這里沒有畫出onInterceptTouchEvent()方法)

上面的ViewGroup的Touch事件分發(fā)就告一段落先,因為這里要調(diào)用TextView(也就是View)的dispatchTouchEvent()方法,所以我們先分析View的dispatchTouchEvent()方法在將上面的繼續(xù)下去

 

View的Touch事件分發(fā)機制

我們還是先看View的dispatchTouchEvent()方法的源碼

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public boolean dispatchTouchEvent(MotionEvent event) {  

  2.         if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&  

  3.                 mOnTouchListener.onTouch(this, event)) {  

  4.             return true;  

  5.         }  

  6.         return onTouchEvent(event);  

  7.     }  

在這個方法里面,先進行了一個判斷

第一個條件mOnTouchListener就是我們調(diào)用View的setTouchListener()方法設置的

第二個條件是判斷View是否為enabled的, View一般都是enabled,除非你手動設置為disabled

第 三個條件就是OnTouchListener接口的onTouch()方法的返回值了,如果調(diào)用了setTouchListener()設置 OnTouchListener,并且onTouch()方法返回true,View的dispatchTouchEvent()方法就直接返回 true,否則就執(zhí)行View的onTouchEvent() 并返回View的onTouchEvent()的值
現(xiàn)在你了解了View的 onTouchEvent()方法和onTouch()的關(guān)系了吧,為什么Android提供了處理Touch事件onTouchEvent()方法還要 增加一個OnTouchListener接口呢?我覺得OnTouchListener接口是對處理Touch事件的屏蔽和擴展作用吧,屏蔽作用我就不舉 例介紹了,看上面的源碼就知道了,我就說下擴展吧,比如我們要打印View的Touch的點的坐標,我們可以自定義一個View如下

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public class CustomView extends View {  

  2.       

  3.     public CustomView(Context context, AttributeSet attrs) {  

  4.         super(context, attrs);  

  5.     }  

  6.   

  7.     public CustomView(Context context, AttributeSet attrs, int defStyle) {  

  8.         super(context, attrs, defStyle);  

  9.     }  

  10.   

  11.     @Override  

  12.     public boolean onTouchEvent(MotionEvent event) {  

  13.           

  14.         Log.i("tag""X的坐標 = " + event.getX() + " Y的坐標 = " + event.getY());  

  15.           

  16.         return super.onTouchEvent(event);  

  17.     }  

  18.   

  19. }  

也可以直接對View設置OnTouchListener接口,在return的時候調(diào)用下v.onTouchEvent()

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. view.setOnTouchListener(new OnTouchListener() {  

  2.               

  3.             @Override  

  4.             public boolean onTouch(View v, MotionEvent event) {  

  5.                   

  6.                 Log.i("tag""X的坐標 = " + event.getX() + " Y的坐標 = " + event.getY());  

  7.                   

  8.                 return v.onTouchEvent(event);  

  9.             }  

  10.         });  

這樣子也實現(xiàn)了我們所需要的功能,所以我認為OnTouchListener是對onTouchEvent()方法的一個屏蔽和擴展作用,假如你有不一樣的理解,你也可以告訴我下,這里就不糾結(jié)這個了。

我們再看View的onTouchEvent()方法

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public boolean onTouchEvent(MotionEvent event) {  

  2.       final int viewFlags = mViewFlags;  

  3.   

  4.       if ((viewFlags & ENABLED_MASK) == DISABLED) {  

  5.           return (((viewFlags & CLICKABLE) == CLICKABLE ||  

  6.                   (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));  

  7.       }  

  8.   

  9.       //如果設置了Touch代理,就交給代理來處理,mTouchDelegate默認是null  

  10.       if (mTouchDelegate != null) {  

  11.           if (mTouchDelegate.onTouchEvent(event)) {  

  12.               return true;  

  13.           }  

  14.       }  

  15.   

  16.       //如果View是clickable或者longClickable的onTouchEvent就返回true, 否則返回false  

  17.       if (((viewFlags & CLICKABLE) == CLICKABLE ||  

  18.               (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {  

  19.           switch (event.getAction()) {  

  20.               case MotionEvent.ACTION_UP:  

  21.                   boolean prepressed = (mPrivateFlags & PREPRESSED) != 0;  

  22.                   if ((mPrivateFlags & PRESSED) != 0 || prepressed) {  

  23.                       boolean focusTaken = false;  

  24.                       if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {  

  25.                           focusTaken = requestFocus();  

  26.                       }  

  27.   

  28.                       if (!mHasPerformedLongPress) {  

  29.                           removeLongPressCallback();  

  30.   

  31.                           if (!focusTaken) {  

  32.                               if (mPerformClick == null) {  

  33.                                   mPerformClick = new PerformClick();  

  34.                               }  

  35.                               if (!post(mPerformClick)) {  

  36.                                   performClick();  

  37.                               }  

  38.                           }  

  39.                       }  

  40.   

  41.                       if (mUnsetPressedState == null) {  

  42.                           mUnsetPressedState = new UnsetPressedState();  

  43.                       }  

  44.   

  45.                       if (prepressed) {  

  46.                           mPrivateFlags |= PRESSED;  

  47.                           refreshDrawableState();  

  48.                           postDelayed(mUnsetPressedState,  

  49.                                   ViewConfiguration.getPressedStateDuration());  

  50.                       } else if (!post(mUnsetPressedState)) {  

  51.                           mUnsetPressedState.run();  

  52.                       }  

  53.                       removeTapCallback();  

  54.                   }  

  55.                   break;  

  56.   

  57.               case MotionEvent.ACTION_DOWN:  

  58.                   if (mPendingCheckForTap == null) {  

  59.                       mPendingCheckForTap = new CheckForTap();  

  60.                   }  

  61.                   mPrivateFlags |= PREPRESSED;  

  62.                   mHasPerformedLongPress = false;  

  63.                   postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());  

  64.                   break;  

  65.   

  66.               case MotionEvent.ACTION_CANCEL:  

  67.                   mPrivateFlags &= ~PRESSED;  

  68.                   refreshDrawableState();  

  69.                   removeTapCallback();  

  70.                   break;  

  71.   

  72.               case MotionEvent.ACTION_MOVE:  

  73.                   final int x = (int) event.getX();  

  74.                   final int y = (int) event.getY();  

  75.   

  76.                   //當手指在View上面滑動超過View的邊界,  

  77.                   int slop = mTouchSlop;  

  78.                   if ((x < 0 - slop) || (x >= getWidth() + slop) ||  

  79.                           (y < 0 - slop) || (y >= getHeight() + slop)) {  

  80.                       // Outside button  

  81.                       removeTapCallback();  

  82.                       if ((mPrivateFlags & PRESSED) != 0) {  

  83.                           removeLongPressCallback();  

  84.   

  85.                           mPrivateFlags &= ~PRESSED;  

  86.                           refreshDrawableState();  

  87.                       }  

  88.                   }  

  89.                   break;  

  90.           }  

  91.           return true;  

  92.       }  

  93.   

  94.       return false;  

  95.   }  

這 個方法也是比較長的,我們先看第4行,如果一個View是disabled, 并且該View是Clickable或者longClickable, onTouchEvent()就不執(zhí)行下面的代碼邏輯直接返回true, 表示該View就一直消費Touch事件,如果一個enabled的View,并且是clickable或者longClickable 的,onTouchEvent()會執(zhí)行下面的代碼邏輯并返回true,綜上,一個clickable或者longclickable的View是一直消 費Touch事件的,而一般的View既不是clickable也不是longclickable的(即不會消費Touch事件,只會執(zhí)行 ACTION_DOWN而不會執(zhí)行ACTION_MOVE和ACTION_UP) Button是clickable的,可以消費Touch事件,但是我 們可以通過setClickable()和setLongClickable()來設置View是否為clickable和longClickable。 當然還可以通過重寫View的onTouchEvent()方法來控制Touch事件的消費與否

我們在看57行的ACTION_DOWN, 新建一個CheckForTap,我們看看CheckForTap是什么

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. private final class CheckForTap implements Runnable {  

  2.        public void run() {  

  3.            mPrivateFlags &= ~PREPRESSED;  

  4.            mPrivateFlags |= PRESSED;  

  5.            refreshDrawableState();  

  6.            if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {  

  7.                postCheckForLongClick(ViewConfiguration.getTapTimeout());  

  8.            }  

  9.        }  

  10.    }  

原 來是個Runnable對象,然后使用Handler的post方法延時ViewConfiguration.getTapTimeout()執(zhí)行 CheckForTap的run()方法,在run方法中先判斷view是否longClickable的,一般的View都是 false, postCheckForLongClick(ViewConfiguration.getTapTimeout())這段代碼就是執(zhí)行長 按的邏輯的代碼,只有當我們設置為longClickble才會去執(zhí)行 postCheckForLongClick(ViewConfiguration.getTapTimeout()),這里我就不介紹了

由于考慮到文章篇幅的問題,我就不繼續(xù)分析View的長按事件和點擊事件了,在這里我直接得出結(jié)論吧

長 按事件是在ACTION_DOWN中執(zhí)行,點擊事件是在ACTION_UP中執(zhí)行,要想執(zhí)行長按事件,這個View必須是longclickable的, 也許你會納悶,一般的View不是longClickable為什么也會執(zhí)行長按事件呢?我們要執(zhí)行長按事件必須要調(diào)用 setOnLongClickListener()設置OnLongClickListener接口,我們看看這個方法的源碼

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public void setOnLongClickListener(OnLongClickListener l) {  

  2.      if (!isLongClickable()) {  

  3.          setLongClickable(true);  

  4.      }  

  5.      mOnLongClickListener = l;  

  6.  }  

看到?jīng)]有,如果這個View不是longClickable的,我們就調(diào)用setLongClickable(true)方法設置為longClickable的,所以才會去執(zhí)行長按方法onLongClick();
 

要 想執(zhí)行點擊事件,這個View就必須要消費ACTION_DOWN和ACTION_MOVE事件,并且沒有設置OnLongClickListener的 情況下,如果設置了OnLongClickListener的情況下,需要onLongClick()返回false才能執(zhí)行到onClick()方法, 也許你又會納悶,一般的View默認是不消費touch事件的,這不是和你上面說的相違背嘛,我們要向執(zhí)行點擊事件必須要調(diào)用 setOnClickListener()來設置OnClickListener接口,我們看看這個方法的源碼就知道了

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. public void setOnClickListener(OnClickListener l) {  

  2.      if (!isClickable()) {  

  3.          setClickable(true);  

  4.      }  

  5.      mOnClickListener = l;  

  6.  }  

所以說一個enable的并且是clickable的View是一直消費touch事件的,所以才會執(zhí)行到onClick()方法


 

對 于View的Touch事件的分發(fā)機制算是告一段落了,從上面我們可以得出TextView的dispatchTouchEvent()的返回false 的,即不消費Touch事件。我們就要往上看RelativeLayout的dispatchTouchEvent()方法的51行,由于 TextView.dispatchTouchEvent()為false, 導致mMotionTarget沒有被賦值,還是null, 繼續(xù)往下走執(zhí)行RelativeLayout的dispatchTouchEvent()方法, 來到第84行, 判斷target是否為null,這個target就是mMotionTarget,滿足條件,執(zhí)行92行的 super.dispatchTouchEvent(ev)代碼并返回, 這里調(diào)用的是RelativeLayout父類View的dispatchTouchEvent()方法,由于RelativeLayout沒有設置 onTouchListener, 所以這里直接調(diào)用RelativeLayout(其實就是View, 因為RelativeLayout沒有重寫onTouchEvent())的onTouchEvent()方法 由于RelativeLayout既不是clickable的也是longClickable的,所以其onTouchEvent()方法false, RelativeLayout的dispatchTouchEvent()也是返回false,這里就執(zhí)行完了RelativeLayout的 dispatchTouchEvent()方法

繼 續(xù)執(zhí)行FrameLayout的dispatchTouchEvent()的第51行,由于 RelativeLayout.dispatchTouchEvent()返回的是false, 跟上面的邏輯是一樣的, 也是執(zhí)行到92行的super.dispatchTouchEvent(ev)代碼并返回,然后執(zhí)行FrameLayout的 onTouchEvent()方法,而FrameLayout的onTouchEvent()也是返回false,所以FrameLayout的 dispatchTouchEvent()方法返回false,執(zhí)行完畢FrameLayout的dispatchTouchEvent()方法

在上面的我就不分析了,大家自行分析一下,跟上面的邏輯是一樣的,我直接畫了個圖來幫大家理解下(這里沒有畫出onInterceptTouchEvent()方法)

所 以我們點擊屏幕上面的TextView的事件分發(fā)流程是上圖那個樣子的,表示Activity的View都不消費ACTION_DOWN事件,所以就不能 在觸發(fā)ACTION_MOVE, ACTION_UP等事件了,具體是為什么?我還不太清楚,畢竟從Activity到TextView這一層是分析不出來的,估計是在底層實現(xiàn)的。

 

但 如果將TextView換成Button,流程是不是還是這個樣子呢?答案不是,我們來分析分析一下,如果是Button , Button是一個clickable的View,onTouchEvent()返回true, 表示他一直消費Touch事件,所以Button的dispatchTouchEvent()方法返回true, 回到RelativeLayout的dispatchTouchEvent()方法的51行,滿足條件,進入到if方法體,設置 mMotionTarget為Button,然后直接返回true, RelativeLayout的dispatchTouchEvent()方法執(zhí)行完畢, 不會調(diào)用到RelativeLayout的 onTouchEvent()方法

然后到FrameLayout的dispatchTouchEvent()方法的51行,由于 RelativeLayout.dispatchTouchEvent()返回true, 滿足條件,進入if方法體,設置mMotionTarget為RelativeLayout,注意下,這里的mMotionTarget跟 RelativeLayout的dispatchTouchEvent()方法的mMotionTarget不是同一個哦,因為他們是不同的方法中的,然 后返回true

同理FrameLayout的dispatchTouchEvent()也是返回true, DecorView的 dispatchTouchEvent()方法也返回true, 還是畫一個流程圖(這里沒有畫出onInterceptTouchEvent()方法)給大家理清下

從 上面的流程圖得出一個結(jié)論,Touch事件是從頂層的View一直往下分發(fā)到手指按下的最里面的View,如果這個View的 onTouchEvent()返回false,即不消費Touch事件,這個Touch事件就會向上找父布局調(diào)用其父布局的onTouchEvent() 處理,如果這個View返回true,表示消費了Touch事件,就不調(diào)用父布局的onTouchEvent()

 

接下來我們用一個自定義的ViewGroup來替換RelativeLayout,自定義ViewGroup代碼如下

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. package com.example.androidtouchevent;  

  2.   

  3. import android.content.Context;  

  4. import android.util.AttributeSet;  

  5. import android.view.MotionEvent;  

  6. import android.widget.RelativeLayout;  

  7.   

  8. public class CustomLayout extends RelativeLayout {  

  9.       

  10.     public CustomLayout(Context context, AttributeSet attrs) {  

  11.         super(context, attrs, 0);  

  12.     }  

  13.   

  14.     public CustomLayout(Context context, AttributeSet attrs, int defStyle) {  

  15.         super(context, attrs, defStyle);  

  16.     }  

  17.   

  18.     @Override  

  19.     public boolean onTouchEvent(MotionEvent event) {  

  20.         return super.onTouchEvent(event);  

  21.     }  

  22.   

  23.     @Override  

  24.     public boolean onInterceptTouchEvent(MotionEvent ev) {  

  25.         return true;  

  26.     }  

  27.       

  28.   

  29. }  

我們就重寫了onInterceptTouchEvent(),返回true, RelativeLayout默認是返回false, 然后再CustomLayout布局中加一個Button ,如下圖

我們這次不從DecorView的dispatchTouchEvent()分析了,直接從CustomLayout的dispatchTouchEvent()分析

我 們先看ACTION_DOWN 來到25行,由于我們重寫了onInterceptTouchEvent()返回true, 所以不走這個if里面,直接往下看代碼,來到84行, target為null,所以進入if方法里面,直接調(diào)用super.dispatchTouchEvent()方法, 也就是View的dispatchTouchEvent()方法,而在View的dispatchTouchEvent()方法中是直接調(diào)用View的 onTouchEvent()方法,但是CustomLayout重寫了onTouchEvent(),所以這里還是調(diào)用CustomLayout的 onTouchEvent(), 這個方法返回false, 不消費Touch事件,所以不會在觸發(fā)ACTION_MOVE,ACTION_UP等事件了,這里我再畫一個流程圖吧(含有 onInterceptTouchEvent()方法的)

 

好了,就分析到這里吧,差不多分析完了,還有一種情況沒有分析到,例如我將CustomLayout的代碼改成下面的情形,Touch事件又是怎么分發(fā)的呢?我這里就不帶大家分析了

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片

  1. package com.example.androidtouchevent;  

  2.   

  3. import android.content.Context;  

  4. import android.util.AttributeSet;  

  5. import android.view.MotionEvent;  

  6. import android.widget.RelativeLayout;  

  7.   

  8. public class CustomLayout extends RelativeLayout {  

  9.       

  10.     public CustomLayout(Context context, AttributeSet attrs) {  

  11.         super(context, attrs, 0);  

  12.     }  

  13.   

  14.     public CustomLayout(Context context, AttributeSet attrs, int defStyle) {  

  15.         super(context, attrs, defStyle);  

  16.     }  

  17.   

  18.     @Override  

  19.     public boolean onTouchEvent(MotionEvent event) {  

  20.         return super.onTouchEvent(event);  

  21.     }  

  22.   

  23.     @Override  

  24.     public boolean onInterceptTouchEvent(MotionEvent ev) {  

  25.         if(ev.getAction() == MotionEvent.ACTION_MOVE){  

  26.             return true;  

  27.         }  

  28.         return super.onInterceptTouchEvent(ev);  

  29.     }  

  30.       

  31.   

  32. }  

這篇文章的篇幅有點長,如果你想了解Touch事件的分發(fā)機制,你一定要認真看完,下面來總結(jié)一下吧

1.Activity的最頂層Window是PhoneWindow,PhoneWindow的最頂層View是DecorView

2.一個clickable或者longClickable的View會永遠消費Touch事件,不管他是enabled還是disabled的

3.View的長按事件是在ACTION_DOWN中執(zhí)行,要想執(zhí)行長按事件該View必須是longClickable的,并且不能產(chǎn)生ACTION_MOVE

4.View的點擊事件是在ACTION_UP中執(zhí)行,想要執(zhí)行點擊事件的前提是消費了ACTION_DOWN和ACTION_MOVE,并且沒有設置OnLongClickListener的情況下,如設置了OnLongClickListener的情況,則必須使onLongClick()返回false

5.如果View設置了onTouchListener了,并且onTouch()方法返回true,則不執(zhí)行View的onTouchEvent()方法,也表示View消費了Touch事件,返回false則繼續(xù)執(zhí)行onTouchEvent()

6.Touch 事件是從最頂層的View一直分發(fā)到手指touch的最里層的View,如果最里層View消費了ACTION_DOWN事件(設置 onTouchListener,并且onTouch()返回true 或者onTouchEvent()方法返回true)才會觸發(fā)ACTION_MOVE,ACTION_UP的發(fā)生,如果某個ViewGroup攔截了 Touch事件,則Touch事件交給ViewGroup處理

7.Touch 事件的分發(fā)過程中,如果消費了ACTION_DOWN,而在分發(fā)ACTION_MOVE的時候,某個ViewGroup攔截了Touch事件,就像上面那 個自定義CustomLayout,則會將ACTION_CANCEL分發(fā)給該ViewGroup下面的Touch到的View,然后將Touch事件交 給ViewGroup處理,并返回true

 

?



 

穩(wěn)定

產(chǎn)品高可用性高并發(fā)

貼心

項目群及時溝通

專業(yè)

產(chǎn)品經(jīng)理1v1支持

快速

MVP模式小步快跑

承諾

我們選擇聲譽

堅持

10年專注高端品質(zhì)開發(fā)
  • 返回頂部
麻豆产精国品 亚洲三级网站 亚洲AV丁香五月六月婷婷 一级毛片免费播放无卡片 亚洲无码高清中文字幕 人妻AV无码一区二区三区 性开放按摩AV大片 99久久久无码国产精品免费 热99RE久久精品这里都是精品免费 三年片在线观看免费观看大全 一级黄片香蕉视频 激情综合亚洲色婷婷五月app 粗大猛烈进出高潮视频免费看 亚洲日韩av一区二区三区中文 宅男无码av最新无码av专区 最近2019年好看中文字幕视频 美女粉嫩极品国产在线2020 中文字幕人妻无码专区 一级精品大黄毛片 亚洲无码在线免费 亚洲a∨无码天堂在线观看 一区二区熟妇人妻少妇 日韩精品人妻系列无码专区 在线va无卡无码高清 适合女士自慰时看的黄文 亚洲日韩视频免费观看 欧美成人高清WW 日本丰满bbwbbw AV免费网站在线观看 日本一区二区三区免费播放 久久久久亚洲AV成人网人人网站 尤物午夜精品一区二区 亚洲AV永久无码区成人网站 亚洲中文久久久久国产精品 国产成人无码A区在线观看导航 性欧美ⅩXXXX极品少妇小说 亚洲午夜高清拍精品 99亚洲男女激情在线观看 亚洲色无码中文字 亚洲综合激情另类小说区 一本一道波多野结衣av不卡 亚洲精品无码久久久久下载 一本大道久久a久久综合婷婷 在线欧美v日韩v国产精品v 中文无码一区二区三区 中文字幕AV无码一区二区三区电影 亚洲一二区在线观看 五月天国产成人AV免费观看 亚洲中文字幕日韩无码 377P欧洲日本亚洲大胆 亚洲中文乱码在线观看AV 日产精品一品二品三品 一本色道久久综合亚洲 亚洲欧洲成人a∨在线 欧美高清性xxxxhdvideosex 思思久久精品一本到99热 亚洲欧美另类bt自拍区图片 亚洲精品1卡2卡3卡 香蕉97超级碰碰碰视频 亚洲中文字幕久久久久 久久中文精品无码中文字幕下载 欧美丰满老熟妇aaaa片 在线看片免费人成视频国产片 中国少妇偷人HD 免费人妻无码不卡中文字幕系 亚洲欧美日韩国产综合在线一区 精品成人乱色一区二区 亚洲午夜无码久久久久久 精品无码三级在线观看视频 无码免费无线观看在线视频 亚洲AV日韩AV国内 亚洲AV无码潮喷在线观看蜜桃 99re久久资源最新地址 中文字幕无码AV免费久久 国产免费无码一区二区三区 一区二区中文字幕在线观看 在线高清无码视频 亚洲伊人色欲综合网无码中文 曰本女人与动牲交毛片 久久无码精品一区二区三区 妺妺跟我一起洗澡没忍住 亚洲日韩欧美国产高清αv 新版天堂а√在线地址 国产美女精品一区二区三区 一本久久伊人热热精品中文 在线 | 国产精品99传媒A 免费网站看SM调教视频 亚洲人成网站18禁止大APP 一本久道久久综合狠狠躁AV 亚洲AV成人网站在线观看 美女内射无套日韩免费播放 一本大道东京热无码AV 一本一道精品欧美中文字幕 AV无码中文字幕不卡一区二区三区 狠狠色老熟妇老熟女 欧美交换配乱吟粗大25P 精品成在人线AV无码免费看 欧美成人精品第一区二区三区 亚洲AV毛片一区二区三区 国产成人欧美综合在线影院 亚洲成AV人综合在线观看 正在播放国产真实露脸高清 亚洲制服丝袜中文字幕在线 亚洲五十路精品无码专区 乱色熟女综合一区二区三区 天天av天天翘天天综合网 亚洲精选无码久久久 天堂а√在线中文在线新版 99视频精品全部在线观看 亚洲天天做日日做天天欢 国产乱码精品一区三上 亚洲一区二区精品中文字幕 西西444WWW大胆无码视频下载 亚洲av无码成人精品区一本二本 直接在线观看黄网站免费视频 性欧美ⅩXX1819内谢 精品久久久久久国产潘金莲 两性色午夜视频免费播放 中国老太卖婬HD播放 又大又粗又硬又黄的免费视频 国产成人综合久久免费导航 亚洲级αv无码毛片久久精品 久久精品成人无码观看56 一道本不卡一区 久久久久国产精品熟女影院 无码人妻一区二区三区av aⅴ精品无码无卡在线观看 亚洲视频东京热无码二区 国内精品九九久久久精品 狠狠色丁香婷婷综合潮喷 日本高清视频网站WWW692RRC 最新国产精品自产在线观看 国产人成无码视频在线观看 门国产乱子视频观看 中文AV无码人妻一区二区三区 无码中文av波多野吉衣迅雷下载 一区精品麻豆经典 中文字幕在线中字日韩 中文无码一区二区三区 国产亚洲精品俞拍视频 羞羞午夜福利院免费观看日本 激情 小说 亚洲 图片 伦 羞羞视频最新地址发布页 欧美人牲交A欧美精区日韩 好爽…又高潮了粉色视频 一本大道东京热无码AV 在线观看一级无码毛片 无码8090精品 亚洲中文一本无码av在线无码 99久久综合精品五月天 免费无码观看的AV在线播放 天码av无码一区二区三区四区 在线观看亚洲免费视频 亚洲AV永久中文无码精品综合 狠狠色噜噜狠狠狠888777米奇 性少妇VIDEOXXⅩ欧美69 美女裸体无遮挡免费视频网站 亚洲精品成人无限看 亚洲国产丝袜精品一区 poronodrome另类极品 亚洲国产初高中生女AV 最新日韩欧美不卡一二三区 在线观看日韩www视频免费 在线观看免费网页欧美成 人人爽天天碰天天躁夜夜躁 国产AV国片精品有毛 野外三级国产在线观看 翘臀少妇被扒开屁股日出水爆乳 亚洲熟女乱色一区二区三区丝袜 av天堂亚洲国产av 亚洲午夜精品A品久久 国产日韩成人内射视频 亚洲日韩在线中文字幕综合 亚洲中文久久精品无码99 一本色道久久综合亚洲精品加 国产无遮挡又黄又爽网站 亚洲女初尝黑人巨高清 在线观看肉片H漫网站免费 再深点灬舒服灬太大了av 产精品无码久久_亚洲国产精 不卡高清AV手机在线观看 国产成人亚洲综合色 色五月五月丁香亚洲综合网 亚洲无码黄色视频在线观看 久久综合九色综合欧洲98 欧美亚洲日本国产其他 亚洲综合久久无码色噜噜赖水 天堂а√在线官网 一区二区三区精密机械公司 亚洲一区精品伊人久久 2024AV天堂手机在线观看 亚洲一区二区欧美色妞影院 亚洲中文字幕精品有码在线 亚洲成AV人片一区二区不卡 国产精品美女久久久久久久久 伊人久久大香线蕉观看 久久久久99精品成人片欧美 最近的中文字幕在线看视频 又爽又湿又野视频免费看看 一本色道久久—综合亚州 亚洲hairy多毛pics大全 中文字幕欧美成人免费 亚洲一级大黄大色毛片 亚洲欧美日韩一区在线观看 天天天天躁天天爱天天碰2018 中文在线а√在线天堂中文 无码AV专区丝袜专区 自拍亚洲综合在线精品 亚洲日韩一级在线毛 亚洲av综合色区无码一二三区 亚洲色欧美色国产综合色 亚洲一级a视频在线 污污内射久久一区二区欧美日韩 国产sm调教折磨视频 孩交VIDEOSSEX精品 国产人碰人摸人爱视频 精品欧美H无遮挡在线看中文 jlzzjlzzjlz亚洲日本 亚洲日韩成人 中文字幕在线永久资源 亚洲一卡欧美成a人片在线观看久 国产精品99久久久久久WWW 亚洲午夜在线观看专区 中文国产高清综合乱色视频在线播放 一区二区三区无码动漫 日韩人妻无码精品久久久不卡 在线观看精品视频网站 亚洲av日韩av天堂影片精品 色噜噜一区二区三区 饥渴少妇av无码影片 亚洲精品无码专区在线观看 大伊香蕉在线观看视频 亚洲成AV人片在线观看高清 mm131午夜福利在线观看 免费A级毛片高清视频不卡 最近日本MV字幕免费观看视频 好紧好滑好湿好爽免费视频 媚药侵犯调教放荡在线观看 国产日韩AV免费无码一区二区三区 FREEZEFRAME丰满少妇 亚洲网站免费视频精品一区 中文天堂在线www 亚洲一区二区三区无码精品 又大又硬又爽18禁免费看 亚洲精品成人网站在线 中文字幕日韩精品亚洲七区 CHINESE 麻豆 HD XXXX MOVIESQ 中文字幕成人在线观看网站 亚洲五月天婷婷 少妇乳大丰满在线播放 亚洲色一区二区三区四区 日本xXXx色视频在线观看 精品无码一区二区三区在线 在线观看国产无码片视频 一本色道久久88加勒比久久综合 特级av毛片免费观看 日韩 欧美 动漫 国产 制服 亚洲AV久播在线播放青青尤物电 18黑白丝水手服自慰喷水网站 无码国产精品一区二区免费久久 亚洲一区二区三区在线视频 又色又爽又黄的三级视频 嫩草影院精品视频在线观看 超碰97人人做人人爱综合 双乳奶水饱满少妇呻吟免费看 亚洲第一狼人天堂网亚洲av CHINESE熟女熟妇 www国产亚洲精品 国产内射爽爽大片视频社区在线 欧美性猛交XXXX黑人猛交 亚洲一级av在线试看 亚洲一区二区三区国产 一级特黄大片欧美久久久 亚洲国产精品久久一线app 蜜臀av在线 一级全黄裸体免费观看视频 少妇高潮太爽了在线观看 无码毛片aaa在线 精品无码三级在线观看视频 亚洲中文字幕va毛片 最近最新高清中文字幕 在线观看亚洲欧美不卡视频 自拍视频亚洲综合在线精品 少妇的丰满2中文字幕 国产极品白嫩精品 先锋影音xfyy5566男人资源 国产欧美色一区二区三区 日韩免费A级毛片无码A∨ 在线日产欧美精品 午夜福利视频合集1000 亚洲永久精品自拍偷拍 亚洲无码高清中文字幕 亚洲熟妇乱子伦精品 一级少妇免费喷水视频 中国女人和老外的毛片 一级看片免费视频 国产内射在线激情一区 自拍偷自拍亚洲精品被多人伦好爽 一中文字幕无码一区二区三区 性欧美熟妇VIDEOFREESEX 欧美丰满熟妇hdxx 日日猛噜噜狠狠扒开双腿小说 亚洲乱码日产一区三区 大桥未久亚洲无AV码在线 中国少妇无码专区 一区二区三区线日本 亚洲精品国产情侣Av在线 亚洲免费鲁丝片 一级特色特黄视频 久久久无码一区二区三区 在线观看国产中文字幕 亚洲午夜精品一级在线播放 在线高清理伦片A 夜夜狂射影院欧美极品 免费a级毛片永久免费 亚洲国产人在线播放首页 国产精品久久久久久久久久久久午衣片 四虎永久免费观看在线 最新高清中文字幕免费mv 精品福利视频一区二区三区 另类 专区 欧美 制服丝袜 高跟翘臀老师后进式视频 性xxxxBBBB av资源站最稳定的资源站 天堂8中文在线最新版在线 国产精品天干天干综合网 亚洲 卡通 欧美 制服 中文 狠狠色婷婷久久综合频道日韩 亚洲成a人片77777群色 一本色道久久99一综合 中文字幕精品亚洲人成 亚洲午夜激情视频 天天澡天天添天天摸97影院 免费国产a国产片高清女厕所 亚洲第一福利网站在线 欧洲精品码一区二区三区免费看 国产精品午夜福利在线观看地址 久久WWW免费人成人片 五级黄高潮片90分钟视频 亚洲日韩欧美有码在线 美女疯狂连续喷潮视频 亚洲男女一区二区三区 麻豆人妻少妇精品无码专区 国产情侣作爱视频免费观看 三叶草欧洲码在线 亚洲AV无码国产一区二区 亚洲色AV影院久久无码 国产精品一卡二卡三卡 精品国产亚洲一区二区三区 JULIA无码中文字幕一区 最新国产麻豆aⅴ精品无码 伊人久久综合精品无码 亚洲s久久久久一区二区 亚洲男生自慰XNXX 国产h视频在线观看 亚洲成av不卡无码无码不卡 国产偷录视频叫床高潮 亚洲欧洲偷自拍图片区 大香伊蕉99大香伊蕉免费视频 亚洲男男无套GV大学生 亚洲精品网站在线观看你懂的 中文字幕亚洲欧美日韩2019 四虎精品免费永久免费视频 在线看真人片网站 曰批全过程免费视频在线观看草莓 在线观看www视频 亚洲综合久久2021 亚洲日本三级最新在线不卡 亚洲色成人网站www永久四虎 久久人妻天天av 菠萝菠萝蜜在线观看视频社区 亚洲成av人片在线观高清 天天做天天爱夜夜爽毛片毛片 久久综合九色综合欧洲98 久久精品青青草原伊人 亚洲视频二区 一本一道波多野结衣av黑人 国产亚洲精品超碰热 久久中文精品无码中文字幕下载 亚洲欧美日韩综合一区 亚洲一道AV无码午夜福利 亚洲中文字幕AⅤ天堂 在线播放韩国A级无码片 中文在线天堂а√在线 国产一极内射視颍一 中文无码制服丝袜人妻aⅤ 麻豆久久亚洲AV成人无码电影 亚洲AV无码专区在线亚 国产成人免费ā片在线观看 亚洲色拍自偷自拍com 妺妺窝人体色www婷婷 呦交小u女国产精品天堂视频 精品无码国产一区二区三区AV 免费特级黄毛片 中文国产精品免费 青青青在线视频国产 √天堂资源在线中文8在线最新版 在线看片a 超碰已满18进入 最新无码人妻在线不卡 亚洲日韩色在线影院性色 尤物在线精品视频257 综合欧美日韩国产成人 亚洲中文字幕无码永久在线不卡 日本一卡2卡3卡四卡精品网站 亚洲日本va在线视频观看 亚洲 国产 制服 丝袜 另类 中国亚洲呦女专区 一本色道无码道D∨D在线观看 亚洲制服丝袜精品久久100部 一本久道久久综合多人 亚洲无码高清视频影院 无码一区二区三区老色鬼 最新国产精品自在线观看tv 天天干成人网 狠狠噜天天噜日日噜视频麻豆 亚洲香蕉视频天天爽 夜鲁夜鲁很鲁在线视频 视频 亚洲av怡红院av男人的天堂 野花高清完整版在线观看免费 中文字幕不卡在线视频无码 国 产 精 品 成 人 自 拍 AV 一本大道香蕉久在线播放a 无码国产69精品久久久久孕妇 骚片av蜜桃精品一区 亚洲AV九月在线播放无卡动 在线免费观看毛片 伊人影院蕉久26影院日日中大全 亚洲色无码综合在线观看 粗大在丫头粉嫩里进进出出 亚洲人成网站在线播放影院在线 中文字幕av无码无卡免费 在线观看最新中文字幕AV 日本免费人成视频在线观看 伊人色综合久久天天网 久久99精品国产99久久 亚洲网站免费视频精品一区 又色又爽又黄的视频软件app 99无码熟妇丰满人妻啪啪 一本大道久久A久久综合 99精品国产综合久久久久五月天 夜色欧美一区二区三区 天天爽夜夜爱 亚洲无码在线观看免费 五月天精品视频在线观看 直接在线观看黄网站免费视频 一本色道久久88综合日韩精品 国产成人亚洲精品无码车A 影音先锋18av在线电影 最新高清无码专区无套内谢少妇毛片 天天碰免费上传视频 伊人久久大香线蕉精品哪里 欧美老妇毛茸茸二毛 国产精品久久久久AV 小骚妇下面水多要插视频 久久久久久人妻一区精品 亚洲一区无码精品色下载 久久偷看各类WC女厕嘘嘘 A级毛片100部免费看 一本久道热线在线视频 特级无码a级毛片特黄 人妻忍着娇喘被中进中出视频 亚洲日韩久久综合中文字幕 免费人成网站在线观看欧美 亚洲午夜未满十八勿入 法国少妇XXXX做受 亚洲无码中文字幕在线观看 久久久老熟女一区二区三区 日本三级在线观看免费 曰本特黄大片一级 亚洲视频一区二区日本三级欧美三级 欧美日韩欧美 天堂中文在线8最新版地址 最新中文AV岛国无码免费播放 真实乱子伦露脸 在线不卡高清播放AV网站 在线免费无码不卡 亚洲无码免费在线观看视频 国产中文欧美日韩在线 欧美国产日韩A在线观看 在线播放国产一区精品 亚洲VA中文字幕无码一区 中文无码主页精品视频 国产亚洲精品俞拍视频 最近韩国日本免费高清观看 AV片在线播放 全免费A级毛片免费看视频 国产亚洲日韩在线三区 一本大道香蕉中文在线播放 欧美日韩亚洲国产精品 亚洲愉拍一区二区三区 国产精品成人AV片免费看 真实国产精品视频400部 国语对白露脸XXXXXX 永久免费av无码动漫网站在线 亚洲AV色吊丝无码 日产乱码卡一卡2卡三卡四颐和园 亚洲AV无码久久精品成人 我半夜摸妺妺的奶C了她软件 制服丝袜综合国产精品 永久免费无码成人网站 蜜桃色网视频网站 亚洲中文无码人妻 亚洲欧美人成网站aaa 亚洲av日韩av高潮潮喷无码 中文字幕韩国三级理论久久 波多野结衣一区二区三区高清 在线播放国产一区精品 国产精品一区二区久久乐下载 亚洲成a人v欧美综合天堂下载 韩国V欧美V亚洲V日本V 人C交ZOOZOOXX特 亚洲日本在线观看 天堂va视频一区二区 亚洲av无码av吞精久久 午夜性影院爽爽爽爽爽爽 日本少妇被黑人xxxxx 亚洲午夜一区二区三区在线观看 别揉我奶头~嗯~啊~视频在线观看 小嫩批日出水无码视频免费 亚洲一区二区三区日韩 亚洲AV综合永久无码精品天堂 香蕉久久夜色精品国产 国产成人乱色伦区 青青青在线视频国产 亚洲一区不卡视频 自拍偷区亚洲综合激情 国产精品无码永久免费888 国产精品无码无片在线观看3d 亚洲中文字幕五月 在线观看av不卡网站永久 亚洲天堂av社区成人 欧美老妇人XXXX 伊人久久大香线蕉精品97 久久亚洲欧美国产精品 亚洲综合另类小说色区 一级特黄aa大片免费播放视频 亚洲午夜福利精品无码不卡 一级黄色大片免费观看 老妇XXXXX性开放 亚洲日韩欧美自拍他拍 亚洲精品成人网站在线观看 毛很浓密超多黑毛的少妇 东京热人妻无码人av 一区二区欧美日韩高清免费 亚洲无码在线色资源 蜜桃臀AV高潮无码 欧美亚洲一区二区三区 亚洲综合无码AV一区二区 在线a久青草视频在线观看 亚洲日韩一中文字暮AV 一区二区三区激情综合婷婷色 亚洲最新无码成AV人 丁香花高清在线观看完整版 俄罗斯大荫蒂女人毛茸茸 国产啪精品视频网站免费尤物 少妇被男按摩师按到高潮 粗大猛烈进出高潮视频大全 好爽毛片一区二区三区四 亚洲毛茸茸bbxx 欧美国产成人久久精品 亚洲AV无码专区牛牛影院 女M羞辱调教视频网站 日韩人妻无码精品专区 亚洲国产成人精品无码区四虎 久久亚洲精品情侣 久久久精品国产SM调教网站 国产性猛交╳XXX乱大交 A三级三级成人网站在线视频 xxxxbbbb欧美 亚欧美日韩香蕉在线播放视频 亚洲国产精品久久久天堂不卡海量 亚洲日韩精品乱码中文字幕 亚洲一区欧美二区 免费人妻无码不卡中文字幕系 久久人人爽人人爽人人片AV麻烦 亚洲 日韩 欧美 有码 在线 国语做受对白XXXXX在线 特黄AAAAAAA片免费视频 伊人久久精品亚洲午夜 成人免费视频无码专区 亚洲三级中文字幕 亚洲av永久无码天堂影院黑人 97婷婷狠狠成为人免费视频 一本久道综合久久精品 亚洲 小说 欧美 激情 另类 亚洲AV无码不卡无码国产 亚洲丝袜在线观看 男女啪啪抽搐呻吟高潮动态图 欧美精品18VIDEOSEX性欧美 免费无码又爽又刺激高潮的动态图 亚洲天堂中文字幕在线观看电影 欧美最猛性xxxxx大叫 人妻有码中文字幕 中国zzijzzijzzwww精品 亚洲av综合a∨一区二区 亚洲AV成人久久无码网 在线观看中文精品免费 香蕉久久久久久AV成人 国产极品粉嫩泬免费观看 少妇无码AV无码专区线 亚洲欧美日韩中字视频三区 少妇激情AV一区二区三区 国产二级一片内射视频播放 亚洲人成无码网站在线观看野花 国产精品无码久久av 中文字幕在线亚洲二区 永久免费AV无码动漫网站在线观看 亚洲一区二区中文字幕啪啪 羞羞影院午夜男女爽爽在线观看 JAPANESE国产在线观看 中文字幕人成无码免费视频 亚洲综合在线视频 邻居少妇张开腿让我爽了在线观看 日韩人妻无码精品系列专区 亚洲AⅤ永久无码天堂影院 最新国产精品无码 嫩草91香蕉国产观看免费 狠狠人妻久久久久久综合蜜桃 真实国产乱子伦对白视苹 在线a亚洲v天堂网2018 mcc色导航 亚洲欧洲无码av不卡在线 青青青在线视频国产 成 人 黄 色 网 站 18 欲妇荡岳丰满少妇岳 亚洲中文字幕日韩 亚洲国产区男人本色 国产精品天干天干 又大又粗内射在线观看 日韩人妻无码一区二区三区综合部 欧美综合自拍亚洲综合图片区 亚洲av成人永久网站 在线免费三级片网站 亚洲一线产区二线产区精华 露露亚洲版和国际版的区别 插插射啊爱视频日A级 中国xx爽69护士 国产无遮挡又黄又大又爽 国产自产V一区二区三区C 在线免费观看羞羞视频 亚洲熟妇自偷自拍另欧美 欧美 国产 综合 欧美 视频 伊人婷婷六月狠狠狠去 亚洲AV福利天堂在线观看不卡 凹厕所xxxxbbbb偷拍视频 在线看片免费观看视频 又高潮又刺激又无码国产 伊人精品久久久大香线蕉 在线不卡免费高清播放AV网站 亚洲av日韩aⅴ无码色老头 成人免费看吃奶视频网站 这里只有精品国产 久热中文字幕无码视频 免费永久在线观看黄网站 人妻少妇精品久久久久久 日本高清视频WWWW色 久久精品国产亚洲Av日韩 亚洲乱亚洲乱少妇无码99P 在线观看网站亚洲国产 亚洲人成伊人成综合网中文 国产老熟女网站 18禁在线永久免费观看 亚洲国产精品无码久久sM 亚洲性久久久影视 精品性高朝久久久久久久 中文字幕 制服 亚洲 另类 亚洲AⅤ永久无码一区二区三区 免费午夜爽爽爽www视频十八禁 久久亚洲精品无码AV红樱桃 最新国产精品精品视频 日产精品一区二区 av片在线观看免费光看高清 亚洲综合偷窥自拍 欧美粗大猛烈老熟妇 人妻av无码专区久久 人人妻人人狠人人爽 亚洲国产成人精品一区刚刚 性饥渴艳妇性色生活片在线播放 亚洲熟妇色ⅩXXXX日本 免费无人区一码二码乱码 国语做受对白XXXXX在线 在线天堂中文最新版www下载 伊人热热久久原色播放WWW 一区二区三区水蜜桃 japanese成熟丰满熟妇 亚洲 小说 欧美 中文 在线 亚洲av无码乱码忘忧草亚洲人 内射小寡妇无码 亚洲高清乱码午夜电影网 在线视频欧美国产在线 中文av乱片在线播放 精品无码久久久久久久久 色吊丝av中文字幕 亚洲综合伊人久久大杳蕉 亚洲国产成人久久综合一区 伊人久久大香线蕉免费视频 中文亚洲欧美在线不卡 手机国产乱子伦精品视频 国产精品天天看天天狠 性高湖久久久久久久久AAAAA 在线观看视频一区二区三区 又湿又紧又大又爽A视频男 久久久久亚洲AV无码专区电影 在线精品国无码AV不卡顿 在线播放无码高潮的视频 久久久国产精品亚洲一区 一二三四电影免费观看 一本大道人妻中字幕在线视频 国产精品JIZZ视频 性AV盈盈无码天堂 制服丝袜亚洲中文欧美在线 亚洲AV无码成人网站久久精品大 婬乱丰满熟妇xXxXX性 欧美成人猛交69 亚洲欧洲日产喷水无码 在线丝袜美腿 中文字幕 久久久久88色偷偷 伊人久久大香线蕉综合影视 无码久久精品国产亚洲Av影片 午夜在线观看短无码视频 水牛影视一区二区三区久 影音先锋男人站 free玩弄少妇 亚洲中文日韩欧美v 美女脱了内裤张开腿让男人桶网站 国色天香社区视频免费高清3 午夜福利在线永久视频 日本边添边摸边做边爱喷水 亚洲中文精品视频在线 香蕉在线精品视频在线 性刺激特黄毛片免费视频 伊人久久大香线蕉综合狠狠 日韩人妻无码精品久久免费一 无码人妻丰满熟妇啪啪7774 亚洲精品无码鲁网午夜 亚洲中文字幕无码中文文 各种亲戚关系交换乱小说 亚洲最大AV资源站无码AV网址 久久久综合九色合综国产精品 亚洲一级av无码毛片久久 国产成人亚洲综合网站小说 在线国产无码 国产激情在线观看播放 在线aⅴ免费 一级a做片性视频美女大腿真白 国产精品亚洲一区二区三区在线 精品人妻少妇一区二区 内射少妇一区27P 风流少妇又紧又爽又丰满 影音先锋男人av橹橹色 一区二区无码视频在线观看 尤物99久久国产超碰精品 天天做天天爱夭大综合网 亚洲精品成a人在线观看☆ 亚洲精品不卡av在线播放 亚洲AV福利天堂在线观看不卡 亚洲 国产 欧美 丝袜 日韩 国产免费一区二区三区在线观看 97色成人综合网站 小13箩利洗澡无码视频免费网站 影音先锋女人av女色资源 亚洲成AV人无码综合在线观看 一本久久伊人精品中文字幕 伊人久久综合线亚洲2019 亚洲鲁丝片av无码多人 成年男人裸j网站 亚洲色偷偷偷综合网 亚洲国产一区二区三区亚瑟 国产美女精品一区二区三区 精品一区二区三区在线播放视频 国产精品毛片无遮挡 人妻少妇无码专视频在线 色五月丁香六月欧美综合 亚洲熟女少妇一区二区 国产剧情国产精品一区 黑人巨茎大战白人美女 午夜精品久久久久久久无码 亚洲中文字幕影院 在线观看亚洲黄视频精品九九 97人妻精品一区二区三区 亚洲一区二区三区久久精品 国产精品Www夜色视频 中文国产成人精品久久尤物 日韩精品无码一本二本三本 在线观看国产在线优质精品 久久综合丝袜日本网 浪荡女天天不停挨cao日常视频 蜜桃视频在线观看免费视频网站www 亚洲超碰97无码中文字幕 久久免费看黄a级毛片 一区二区三区四区中文字幕在线观看 双乳被一左一右吃着动态图 亚洲国产精品ⅴa在线播放 精品一区二区三区无码视频 在线观看高清黄网站免费 奶头和荫蒂添的好舒服囗交 亚洲综合在线观看的 亚洲AV九月在线播放无卡动 伊人久久大香线蕉电影院 肥大BBwBBw高潮喷水 国产95在线 | 欧美 亚洲中文字幕无码在线 在线观看肉片av网站免费 国产成人无码18禁午夜福利P 亚洲欧美高清在线中文字幕 中文字幕人妻被公上司喝醉在线 图片区小说区激情区偷拍区 亚洲日韩国产欧美一区二区三区 亚洲精品国产美女久久久 亚洲一级精品视频 亚洲一级av无遮挡毛片 欧美XXXXX在线观看 国产精品久久777777 亚洲最大免费无码电影 在线看片A免费人成动漫 99国内精品久久久久久久 亚洲AV永久无码精品主页 久久精品国产亚洲AV麻豆色欲 久久久国产精华液 级R片内射在线视频播放 亚洲欧美日韩综合一区在线观看 一区二区三区国产高清免费视频 亚洲大成色www永久网站注册 亚洲日韩精品无码AV海量窝窝 亚洲综合激情一区二区三区四区 亚洲制服丝袜久久 一本无码在线一区 一区二区三区精品毛片久久久 亚洲熟妇无码AV在线播放 日本无遮挡真人祼交视频 亚洲AV成人男人的天堂 日日摸夜夜添夜夜添亚洲女人 东京热人妻无码人av 伊人久久精品无码麻豆一区 亚洲伊人久久综合成人网站 在线亚洲精品国产成人AV剧情 自拍 另类 图片区 亚洲 一区二区成人国产精品 亚洲日韩精品无码专区加勒比☆ 最近中文在线字幕在线观看 少妇内射高潮福利炮 野花香高清在线观看视频播放免费 亚洲成Av人片在一线观看 性av无码天堂 亚洲人成网站18禁止大APP 在线看片韩国免费人成视频 中文乱码人妻字幕在线永久 一区二区三区波多野结衣在线观看 国产精成人品日日拍夜夜免费 免费观看的无遮挡AV 在线观看中文无码理论 在线观看亚洲人成影院 亚洲最大成人AV在线天堂网 亚洲乱码伦小说区 医院人妻隔着帘子被中出 最近中文字幕高清中文字幕电影二 在线中文字幕亚洲日韩不卡 玩弄人妻少妇500系列视频 亚洲av无码av日韩av网站 亚洲无人区一区二区三区 亚洲一区在线日韩在线尤物 天天草夜夜爽 国产精品久久久久乳精品爆 国产又黄又爽胸又大免费视频 日日摸夜夜添夜夜添毛片性色av 在线а√天堂中文官网 在线观看黄a∨免费无毒网站 中国国产高清免费av片蜜芽tv 少妇饥渴xxhd麻豆xxhd骆驼 性色生活片久久毛片婬片免费放女人 1区2区3区高清视频 一区二区三区在线黄色视频 日本在线视频www色 中文字幕av无码无卡免费 亚洲日韩国产精品无码一区 最近中文字幕++中文 久久天堂AV综合合色 国产精品亚洲lv粉色 亚洲中文无韩国r级电影 久久人人爽人人爽人人片AV麻烦 亚洲午夜无码片在线观看影院猛 伊人精品无码一区二区三区电影 丰满少妇A级毛片野外 在线中文新版最新版在线 久久精品亚洲中文字幕无码网站 亚洲AV无码成人精品区h 无码性午夜视频在线观看 欧美综合人人做人人爱 在线a亚洲ⅴ天堂网2018 免费无遮挡无码永久视频 国产精品一区二区在线蜜芽TV 永久免费无码日韩视频 在线看黄色AV免费 欲求不满的寂寞人妻中文字幕 欧美伊人久久大香线蕉综合 曰本女人牲交免费视频 一级黄片免费视频 亚洲精品专区成人网站 亚洲熟妇无码另类久久久 欧美性开放BBXXX 我把护士日出水了视频90分钟 AV片在线观看 天堂一区人妻无码 亚洲中文在线字幕 亚洲狠狠成人网 亚洲自成人综合网 97人碰人国内成人免费视频 亚洲AV男人的天堂网址在线观看 午夜无码乱码在线观看 性欧美暴力猛交69 麻豆蜜桃AV蜜臀AV色欲AV 护士被强女千到高潮视频 亚洲爆乳精品无码aaa片 一卡二卡三四卡高清视频在线播放 中文字幕乱码人妻一区二区三区 一级做a爰片欧美一区 乱人伦人妻中文字幕 一二三区日韩欧美 亚洲中文字幕在线第二页 在线观看一级毛片 亚洲国产AⅤ美女黄网站 最近中文字幕大全 亚洲三级黄色 亚洲最新无码精品视频2021 亚洲伊人久久成人综合网 一卡二卡3卡四卡吗日韩国产 亚洲av无码理论亚洲毛片 亚洲最大免费无码电影 无套内射极品少妇CHINESE 尤物yw193国产在线精品 亚洲一级国产毛片在线看 在线a毛片免费视频观看 色先锋AV资源中文字幕 亚洲欧美激情四射在线日 最美情侣中文字幕mv百度 内射交换多P国产 一个妈妈的女儿3在线观看中文版 欧美人伦禁忌DVD 国产一区二区三区免费看 亚洲人成线无码7777 亚洲精品1卡2卡3卡 久久ER99热精品一区二区 亚洲国产精品成人久久 亚洲第一极品精品无码久久 99久久er这里只有精品18 人妻中出受孕 中文字幕在线 一级特黄aaa大片29 亚洲爆乳AAA无码专区 国产99网站免在线观看 亚洲成年AV天堂动漫播放器 强奷乱码中文字幕熟女一 亚洲人成无码网站www 在线精品自拍亚洲第一区 亚洲成av人片香蕉片 国产成人无码精品一区不卡 在线成人精品国产区免费 久久夜色精品国产 一级毛片免费看精品视频在线 亚洲一区二区免费 少妇人妻无码专区视频免费 亚洲人成日韩中文字幕无卡 亚洲第一天堂无码专区5G 强行18分钟处破痛哭AV 久久久中文久久久无码 亚洲日韩中文字幕在线播放 在线成人爽A毛片免费软件 50岁熟妇大白屁股真爽 国产两女互慰高潮视频在线观看 一区不卡在线观看 精品一区精品二区制服 亚洲一级无码日韩不卡二区 亚洲无码免费视频国产 在办公室轮流澡到高潮h 欧美精品免费观看二区 中无码人妻丰满熟妇啪啪 亚洲精品无码鲁网午夜 XXXX内射中国老妇 少妇激情艳情综合小视频 一级毛片女人喷潮视频 公交车大龟廷进我身体里视频 国产高清在线观看av片 最新69国产成人精品视频 尤物在线视频国产区 亚洲AV无一区二区三区久久 又黄又粗又大的色网视频 色吊丝av中文字幕 中文字幕一本性无码 а√天堂8资源中文在线 日韩精品一区二区亚洲AV观看 亚洲av永久无码精品桃花岛知道 亚洲AV无码无线在线观看 精精国产xxxx视频在线 好紧好大快点舒服使劲 欧美高清性xxxxhdvideosex JIZZJIZZ国产 又污又黄无遮掩的网站 一本大道精品久久无码蜜桃AV 1000部无遮挡拍拍拍免费视频观看 亚洲漂亮少妇毛茸茸 香港三级韩国三级日本三级
东兰县| 冷水江市| 湟中县| 通海县| 遵义市| 奎屯市| 辽宁省| 花莲县| 建阳市| 德惠市| 安陆市| 灵石县| 泽州县| 垦利县| 昆山市| 健康| 犍为县| 龙南县| 巨野县| 彭水| 商水县| 富民县| 德令哈市| 阿图什市| 夏津县| 金寨县| 朔州市| 咸阳市| 巨鹿县| 青川县| 招远市| 永宁县| 巩义市| 阜新| 麻江县| 和田县| 丹棱县| 永嘉县| 忻州市| 丽江市| 罗山县|