91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中DrawerLayout+ViewPager滑動沖突的解決方法

發布時間:2020-10-07 02:52:52 來源:腳本之家 閱讀:196 作者:Hevin丶 欄目:移動開發

DrawerLayout 是 Android 官方的側滑菜單控件,而 ViewPager 相信大家都很熟悉了。今天這里就講一下當在 DrawerLayout 中嵌套 ViewPager 時,要如何解決滑動沖突的問題,效果如下:

Android中DrawerLayout+ViewPager滑動沖突的解決方法

首先,讓我們先來解決 DrawerLayout 和 ViewPager 的側滑事件沖突。當 DrawerLayout 中嵌套 ViewPager 時,側滑默認是執行 DrawerLayout 的側滑事件,因為 Android 的事件分發是從 外層 ViewGroup 向里逐級傳遞到 View 的。
所以會先執行 DrawerLayout 的 onTouchEvent 方法:

@Override
public boolean onTouchEvent(MotionEvent ev) {
  mLeftDragger.processTouchEvent(ev); 
  mRightDragger.processTouchEvent(ev); 
  final int action = ev.getAction(); boolean wantTouchEvents = true; 
  switch (action & MotionEventCompat.ACTION_MASK) { 
    case MotionEvent.ACTION_DOWN: { 
      final float x = ev.getX(); 
      final float y = ev.getY(); 
      mInitialMotionX = x; 
      mInitialMotionY = y; 
      mDisallowInterceptRequested = false; 
      mChildrenCanceledTouch = false; 
      break; 
    } 
    case MotionEvent.ACTION_UP: { 
      final float x = ev.getX(); 
      final float y = ev.getY(); 
      boolean peekingOnly = true;
      final View touchedView = mLeftDragger.findTopChildUnder((int) x, (int) y); 
      if (touchedView != null && isContentView(touchedView)) { 
        final float dx = x - mInitialMotionX; 
        final float dy = y - mInitialMotionY; 
        final int slop = mLeftDragger.getTouchSlop(); 
        if (dx * dx + dy * dy < slop * slop) { 
          // Taps close a dimmed open drawer but only if it isn't locked open. 
          final View openDrawer = findOpenDrawer(); 
          if (openDrawer != null) { 
            peekingOnly = getDrawerLockMode(openDrawer) == LOCK_MODE_LOCKED_OPEN; 
          } 
        } 
       } 
      closeDrawers(peekingOnly); 
      mDisallowInterceptRequested = false; 
      break; 
    } 
    case MotionEvent.ACTION_CANCEL: { 
      closeDrawers(true); 
      mDisallowInterceptRequested = false;
      mChildrenCanceledTouch = false; break; 
    } 
  } 
  return wantTouchEvents;
}

可以看到在最后始終返回 wantTouchEvents,也就是返回 true,意味著點擊事件在 DrawerLayout 就被消費掉了,無法傳到 ViewPager。

所以,我們像下面這樣,監聽當 Drawer 打開時,將 DrawerLayout 設置為 LOCK_MODE_LOCKED_OPEN,這樣在 Drawer 被打開時,就能夠觸發 ViewPager 的滑動事件了。

mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() { 
 @Override 
 public void onDrawerSlide(View drawerView, float slideOffset) {

 }

 @Override 
 public void onDrawerOpened(View drawerView) {
  mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
 }

 @Override public void onDrawerClosed(View drawerView) {
  mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); 
 }

 @Override public void onDrawerStateChanged(int newState) {

 }
});

但是,當側邊欄的 ViewPager 滑動到最后一頁,再向左滑動時,我們會希望能夠自然的關閉 Drawer。這就需要我們監聽 ViewPager 的 PageChange 事件,當滑動到最后一頁時,將 DrawerLayout 的 LockMode 設置回 LOCK_MODE_UNLOCKED。

這里,選擇在 DrawerFragment(也就是定義側邊欄的 Fragment) 中定義一個接口:

/** 
* 監聽側邊欄的頁面選擇。 
*/
public interface OnDrawerPageChangeListener { 
 void onPageSelected(boolean isLast);
}

然后讓 MainActivity 實現這個接口:

@Override
public void onPageSelected(boolean isLast) { 
 if (isLast) { 
  mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
 } else if (mDrawerLayout.getDrawerLockMode(GravityCompat.START) == DrawerLayout.LOCK_MODE_UNLOCKED) {
  mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN); 
 }
}

再在 DrawerFragment 中 ViewPager 的 PageChange 事件中使用:

final OnDrawerPageChangeListener drawerPageChangeListener = (OnDrawerPageChangeListener) getActivity();
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
 @Override 
 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

 } 
 @Override 
 public void onPageSelected(int position) { 
  if (position == fragmentList.size() - 1) { 
   drawerPageChangeListener.onPageSelected(true); 
  } else { 
   drawerPageChangeListener.onPageSelected(false); 
  } 
 } 
 @Override 
 public void onPageScrollStateChanged(int state) {

 }
});

這樣我們就解決了 DrawerLayout 和 ViewPager 的側滑事件沖突問題,剩下最后一個要處理的小問題就是在點擊空白區域時,也想要關閉側邊欄,這個就只需要:

// 點擊除開側邊欄的區域會收起側邊欄。
mDrawerLayout.setOnTouchListener(new View.OnTouchListener() { 
 @Override 
 public boolean onTouch(View v, MotionEvent event) { 
  switch (event.getAction()) { 
   case MotionEvent.ACTION_DOWN: 
    mDrawerLayout.closeDrawers();
    break;
  } 
  return false; 
 }
});

到這里就大功告成啦!完整的代碼可以參考項目:jpush/jbox: 極光寶盒,一個基于 JPush 的輕便易用的通知框架。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临夏市| 长兴县| 广饶县| 深泽县| 牙克石市| 于田县| 乌拉特前旗| 阿拉善盟| 阜宁县| 木兰县| 兴仁县| 夏河县| 铁岭市| 新建县| 宜阳县| 获嘉县| 且末县| 集贤县| 府谷县| 库伦旗| 和平县| 桓仁| 满洲里市| 黎平县| 疏附县| 滦南县| 济宁市| 前郭尔| 治多县| 固原市| 永登县| 措勤县| 荔浦县| 四会市| 伊金霍洛旗| 福州市| 嘉定区| 班玛县| 青冈县| 深水埗区| 定远县|