国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

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

2019-12-12 02:41:42
字體:
來源:轉載
供稿:網友

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

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

@Overridepublic 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 實現這個接口:

@Overridepublic 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 的輕便易用的通知框架

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 洛扎县| 冀州市| 武城县| 孟村| 武威市| 大荔县| 洞口县| 西贡区| 萝北县| 囊谦县| 旌德县| 孟村| 景洪市| 安平县| 邢台市| 平阴县| 徐闻县| 高雄县| 张家港市| 紫金县| 嘉荫县| 舟曲县| 集安市| 屯昌县| 永宁县| 赤城县| 淅川县| 建水县| 临泽县| 高唐县| 秭归县| 法库县| 望江县| 旅游| 宜宾市| 华安县| 南部县| 米易县| 佛坪县| 高清| 青龙|