最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android中ViewPager帶來的滑動卡頓問題解決要點解析

 更新時間:2016年06月29日 12:03:38   作者:niorgai  
這里我們主要針對ViewGroup的SwipeRefreshLayout中引入ViewPager所引起的滑動沖突問題進(jìn)行討論,一起來看一下Android中ViewPager帶來的滑動卡頓問題解決要點解析:

問題說明:
當(dāng)SwipeRefreshLayout中放置了ViewPager控件,兩者的滑動會相互沖突.具體表現(xiàn)為ViewPager的左右滑動不順暢,容易被SwipeRefreshLayout攔截(即出現(xiàn)刷新的View).

問題原因:
ViewPager本身是處理了滾動事件的沖突,它在橫向滑動時會調(diào)用requestDisallowInterceptTouchEvent()方法使父控件不攔截當(dāng)前的Touch事件序列.但是SwipeRefreshLayout的requestDisallowInterceptTouchEvent()方法什么也沒有做,所以仍然會攔截當(dāng)前的Touch事件序列.

問題分析:
為什么SwipeRefreshLayout的requestDisallowInterceptTouchEvent()方法什么都不做?

首先SwipeRefreshLayout繼承自ViewGroup.

在requestDisallowInterceptTouchEvent()方法什么都不做的情況下,用戶可以從底部下拉刷新一次拉出LoadingView.
如果方法調(diào)用ViewGroup的requestDisallowInterceptTouchEvent()方法, 可以解決ViewPager的兼容問題,但是用戶在界面底部下拉至頭部后,無法繼續(xù)下拉,需要手指放開一次才能拉出LoadingView.
目標(biāo)分析:
那么為了更加順滑地滾動,想要的效果當(dāng)然是一次性拉出LoadingView.既然ViewPager在左右滑動時才會調(diào)用requestDisallowInterceptTouchEvent()方法,那么SwipeRefreshLayout只應(yīng)該在上下滑動時才攔截Touch事件.

具體邏輯如下:

記錄是否調(diào)用了requestDisallowInterceptTouchEvent()方法,并且設(shè)置為true.
在SwipeRefreshLayout中判斷是否是上下滑動.
如果同時滿足1,2,則調(diào)用super.requestDisallowInterceptTouchEvent(true).
否則調(diào)用super.requestDisallowInterceptTouchEvent(false).
注意:因為ViewGroup的requestDisallowInterceptTouchEvent方法設(shè)置true后,Touch事件在dispatchTouchEvent()方法中就會被攔截,所以需要在dispatchTouchEvent()方法中判斷是否為上下滑動.

實現(xiàn)代碼(部分):

//非法按鍵
private static final int INVALID_POINTER = -1;

//dispatch方法記錄第一次按下的x
private float mInitialDisPatchDownX;

//dispatch方法記錄第一次按下的y
private float mInitialDisPatchDownY;

//dispatch方法記錄的手指
private int mActiveDispatchPointerId = INVALID_POINTER;

//是否請求攔截
private boolean hasRequestDisallowIntercept = false;

@Override
public void requestDisallowInterceptTouchEvent(boolean b) {
  hasRequestDisallowIntercept = b;
  // Nope.
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
  switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN:
      mActiveDispatchPointerId = MotionEventCompat.getPointerId(ev, 0);
      final float initialDownX = getMotionEventX(ev, mActiveDispatchPointerId);
      if (initialDownX != INVALID_POINTER) {
        mInitialDisPatchDownX = initialDownX;
      }
      final float initialDownY = getMotionEventY(ev, mActiveDispatchPointerId);
      if (mInitialDisPatchDownY != INVALID_POINTER) {
        mInitialDisPatchDownY = initialDownY;
      }
      break;
    case MotionEvent.ACTION_MOVE:
      if (hasRequestDisallowIntercept) {
        //解決viewPager滑動沖突問題
        final float x = getMotionEventX(ev, mActiveDispatchPointerId);
        final float y = getMotionEventY(ev, mActiveDispatchPointerId);
        if (mInitialDisPatchDownX != INVALID_POINTER && x != INVALID_POINTER &&
            mInitialDisPatchDownY != INVALID_POINTER && y != INVALID_POINTER) {
          final float xDiff = Math.abs(x - mInitialDisPatchDownX);
          final float yDiff = Math.abs(y - mInitialDisPatchDownY);
          if (xDiff > mTouchSlop && xDiff * 0.7f > yDiff) {
            //橫向滾動不需要攔截
            super.requestDisallowInterceptTouchEvent(true);
          } else {
            super.requestDisallowInterceptTouchEvent(false);
          }
        } else {
          super.requestDisallowInterceptTouchEvent(false);
        }
      }
      break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
      if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
        hasRequestDisallowIntercept = false;
      }
      break;
  }

  return super.dispatchTouchEvent(ev);
}

private float getMotionEventY(MotionEvent ev, int activePointerId) {
  final int index = MotionEventCompat.findPointerIndex(ev, activePointerId);
  if (index < 0) {
    return -1;
  }
  return MotionEventCompat.getY(ev, index);
}

private float getMotionEventX(MotionEvent ev, int activePointerId) {
  final int index = MotionEventCompat.findPointerIndex(ev, activePointerId);
  if (index < 0) {
    return -1;
  }
  return MotionEventCompat.getX(ev, index);
}

相關(guān)文章

最新評論

韩城市| 漳州市| 开原市| 临洮县| 博湖县| 封开县| 扬州市| 东阳市| 资中县| 噶尔县| 大洼县| 张家口市| 太康县| 嵩明县| 米泉市| 石景山区| 稷山县| 玉屏| 怀远县| 东明县| 九寨沟县| 高州市| 海门市| 大连市| 琼结县| 古蔺县| 嵊泗县| 出国| 吴堡县| 亚东县| 得荣县| 平和县| 石河子市| 河东区| 黄陵县| 阿巴嘎旗| 罗甸县| 吉木乃县| 合山市| 天门市| 始兴县|