欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android中DrawerLayout+ViewPager滑動(dòng)沖突的解決方法

 更新時(shí)間:2021年04月06日 15:08:17   作者:Hevin丶  
這篇文章主要為大家詳細(xì)介紹了Android中DrawerLayout+ViewPager滑動(dòng)沖突的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

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

首先,讓我們先來(lái)解決 DrawerLayout 和 ViewPager 的側(cè)滑事件沖突。當(dāng) DrawerLayout 中嵌套 ViewPager 時(shí),側(cè)滑默認(rèn)是執(zhí)行 DrawerLayout 的側(cè)滑事件,因?yàn)?Android 的事件分發(fā)是從 外層 ViewGroup 向里逐級(jí)傳遞到 View 的。
所以會(huì)先執(zhí)行 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,意味著點(diǎn)擊事件在 DrawerLayout 就被消費(fèi)掉了,無(wú)法傳到 ViewPager。

所以,我們像下面這樣,監(jiān)聽(tīng)當(dāng) Drawer 打開(kāi)時(shí),將 DrawerLayout 設(shè)置為 LOCK_MODE_LOCKED_OPEN,這樣在 Drawer 被打開(kāi)時(shí),就能夠觸發(fā) ViewPager 的滑動(dòng)事件了。

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) {

 }
});

但是,當(dāng)側(cè)邊欄的 ViewPager 滑動(dòng)到最后一頁(yè),再向左滑動(dòng)時(shí),我們會(huì)希望能夠自然的關(guān)閉 Drawer。這就需要我們監(jiān)聽(tīng) ViewPager 的 PageChange 事件,當(dāng)滑動(dòng)到最后一頁(yè)時(shí),將 DrawerLayout 的 LockMode 設(shè)置回 LOCK_MODE_UNLOCKED。

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

/** 
* 監(jiān)聽(tīng)側(cè)邊欄的頁(yè)面選擇。 
*/
public interface OnDrawerPageChangeListener { 
 void onPageSelected(boolean isLast);
}

然后讓 MainActivity 實(shí)現(xiàn)這個(gè)接口:

@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 的側(cè)滑事件沖突問(wèn)題,剩下最后一個(gè)要處理的小問(wèn)題就是在點(diǎn)擊空白區(qū)域時(shí),也想要關(guān)閉側(cè)邊欄,這個(gè)就只需要:

// 點(diǎn)擊除開(kāi)側(cè)邊欄的區(qū)域會(huì)收起側(cè)邊欄。
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; 
 }
});

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論