<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ***** **事件分發的使用** [TOC=6] # 1.解決事件滑動沖突的思路及方法 ## 1.1常見的三種情況 第一種情況,滑動方向不同 ![](http://ww1.sinaimg.cn/mw690/9fe4afa0gw1f95qa1uuxuj20g00ca0sz.jpg) 第二種情況,滑動方向相同 ![](http://ww4.sinaimg.cn/mw690/9fe4afa0gw1f95q97u2nlj20vc0i7761.jpg) 第三種情況,上述兩種情況的嵌套 ![](http://ww2.sinaimg.cn/mw690/9fe4afa0gw1f95qao07c2j20dw0i3q3q.jpg) ## 1.2 解決思路 看了上面三種情況,我們知道他們的共同特點是父View 和子View都想爭著響應我們的觸摸事件,但遺憾的是我們的觸摸事件 同一時刻只能被某一個View或者ViewGroup攔截消費,所以就產生了滑動沖突?那既然同一時刻只能由某一個View或者ViewGroup消費攔截,那我們就只需要 決定在某個時刻由這個 View 或者 ViewGroup 攔截事件,另外的 某個時刻由 另外一個 View 或者 ViewGroup 攔截事件,不就OK了嗎?綜上,正如 在?《Android開發藝術》?一書提出的,總共 有兩種解決方案 以下解決思路來自于?《Android開發藝術》?書籍 下面的兩種方法針對第一種情況(滑動方向不同),父View是上下滑動,子View是左右滑動的情況。 ## 1.3 外部解決法 從父View著手,重寫onInterceptTouchEvent方法,在父View需要攔截的時候攔截,不要的時候返回false,為代碼大概 如下 ~~~ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final float x = ev.getX(); final float y = ev.getY(); final int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: mDownPosX = x; mDownPosY = y; break; case MotionEvent.ACTION_MOVE: final float deltaX = Math.abs(x - mDownPosX); final float deltaY = Math.abs(y - mDownPosY); // 這里是夠攔截的判斷依據是左右滑動,讀者可根據自己的邏輯進行是否攔截 if (deltaX > deltaY) { return false; } } return super.onInterceptTouchEvent(ev); } ~~~ ## 1.4 內部解決法 從子View著手,父View先不要攔截任何事件,所有的事件傳遞給 子View,如果子View需要此事件就消費掉,不需要此事件的話就交給 父View處理。 實現思路 如下,重寫子 View的dispatchTouchEvent方法,在Action\_down 動作中通過方法 requestDisallowInterceptTouchEvent(true) 先請求 父 View不要攔截事件,這樣保證子 View 能夠接受到 Action\_move 事件,再在 Action\_move 動作中根據自己的邏輯是否要攔截事件,不需要攔截事件的話再交給 父 View 處理。 ~~~ @Override public boolean dispatchTouchEvent(MotionEvent ev) { int x = (int) ev.getRawX(); int y = (int) ev.getRawY(); int dealtX = 0; int dealtY = 0; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: dealtX = 0; dealtY = 0; // 保證子View能夠接收到Action_move事件 getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: dealtX += Math.abs(x - lastX); dealtY += Math.abs(y - lastY); Log.i(TAG, "dealtX:=" + dealtX); Log.i(TAG, "dealtY:=" + dealtY); // 這里是夠攔截的判斷依據是左右滑動,讀者可根據自己的邏輯進行是否攔截 if (dealtX >= dealtY) { getParent().requestDisallowInterceptTouchEvent(true); } else { getParent().requestDisallowInterceptTouchEvent(false); } lastX = x; lastY = y; break; case MotionEvent.ACTION_CANCEL: break; case MotionEvent.ACTION_UP: break; } return super.dispatchTouchEvent(ev); } ~~~ # 2. ScrollView嵌套ListView或GridView滑動沖突解決方案 開發過程中經常會遇到使用scrollview嵌套listview或gridview的情況,這時由于scrollview攔截消費了滑動事件,所以在listview或gridview區域滑動時該區域無法滑動,而是scrollview整體滑動。 正確的處理應該是當焦點在listview或gridview區域該區域滑動,在區域外則scrollview滑動。 想要解決這個問題,加上如下代碼即可: ~~~ listView.setOnTouchListener(new View.OnTouchListener() {   @Override   public boolean onTouch(View arg0, MotionEvent arg1) {     scrollView.requestDisallowInterceptTouchEvent(true); return false;   } } ~~~ ~~~ public class MyListView extends ListView { public MyListView(Context context) { super(context); } public MyListView(Context context, AttributeSet attrs) { super(context, attrs); } public MyListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } } ~~~ # 3. ViewPager嵌套ViewPager滑動沖突解決方案 ## 內部解決法 從子View ViewPager著手,重寫 子View的 dispatchTouchEvent方法,在子 View需要攔截的時候進行攔截,否則交給父View處理,代碼如下 ~~~ public class ChildViewPager extends ViewPager { private static final String TAG = "xujun"; public ChildViewPager(Context context) { super(context); } public ChildViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { int curPosition; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: curPosition = this.getCurrentItem(); int count = this.getAdapter().getCount(); Log.i(TAG, "curPosition:=" +curPosition); // 當當前頁面在最后一頁和第0頁的時候,由父親攔截觸摸事件 if (curPosition == count - 1|| curPosition==0) { getParent().requestDisallowInterceptTouchEvent(false); } else {//其他情況,由孩子攔截觸摸事件 getParent().requestDisallowInterceptTouchEvent(true); } } return super.dispatchTouchEvent(ev); } } ~~~ # 4. ScrollView嵌套ViewPager滑動沖突解決方案(了解) ## 4.1 外部解決 從 父View ScrollView著手,重寫 OnInterceptTouchEvent方法,在上下滑動的時候攔截事件,在左右滑動的時候不攔截事件,返回 false,這樣確保子View 的dispatchTouchEvent方法會被調用,代碼 如下 ~~~ /** * @ explain:這個ScrlloView不攔截水平滑動事件, * 是用來解決 ScrollView里面嵌套ViewPager使用的 */ public class VerticalScrollView extends ScrollView { public VerticalScrollView(Context context) { super(context); } public VerticalScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public VerticalScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(21) public VerticalScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } private float mDownPosX = 0; private float mDownPosY = 0; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final float x = ev.getX(); final float y = ev.getY(); final int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: mDownPosX = x; mDownPosY = y; break; case MotionEvent.ACTION_MOVE: final float deltaX = Math.abs(x - mDownPosX); final float deltaY = Math.abs(y - mDownPosY); // 這里是否攔截的判斷依據是左右滑動,讀者可根據自己的邏輯進行是否攔截 if (deltaX > deltaY) {// 左右滑動不攔截 return false; } } return super.onInterceptTouchEvent(ev); } } ~~~ ## 4.2 內部解決 通過requestDisallowInterceptTouchEvent(true)方法來影響父View是否攔截事件,我們通過重寫ViewPager的 dispatchTouchEvent()方法,在左右滑動的時候請求父View ScrollView不要攔截事件,其他的時候由子View 攔截事件 ~~~ /** * @ explain:這個 ViewPager是用來解決ScrollView里面嵌套ViewPager的 內部解決法的 */ public class MyViewPager extends ViewPager { private static final String TAG = "xujun"; int lastX = -1; int lastY = -1; public MyViewPager(Context context) { super(context); } public MyViewPager(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { int x = (int) ev.getRawX(); int y = (int) ev.getRawY(); int dealtX = 0; int dealtY = 0; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: dealtX = 0; dealtY = 0; // 保證子View能夠接收到Action_move事件 getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: dealtX += Math.abs(x - lastX); dealtY += Math.abs(y - lastY); Log.i(TAG, "dealtX:=" + dealtX); Log.i(TAG, "dealtY:=" + dealtY); // 這里是否攔截的判斷依據是左右滑動,讀者可根據自己的邏輯進行是否攔截 if (dealtX >= dealtY) { // 左右滑動請求父 View 不要攔截 getParent().requestDisallowInterceptTouchEvent(true); } else { getParent().requestDisallowInterceptTouchEvent(false); } lastX = x; lastY = y; break; case MotionEvent.ACTION_CANCEL: break; case MotionEvent.ACTION_UP: break; } return super.dispatchTouchEvent(ev); } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看