簡單完美解決PullToRefreshLayout中PullableListView嵌套ViewPager時滑動沖突的問題


要實現上拉加載下拉刷新功能,Android原生的控件SwipeRefreshLayout使用起來不是很方便,相信很多人都會選擇PullToRefreshLayout,因為項目需求,在列表上方要加一個banner輪播圖,自然就要給ListView添加一個頭部,里面放一個ViewPager,那么問題就來了,當用手滑動ViewPager時,ViewPager和PullToRefreshLayout的下拉刷新會有沖突,導致滑動ViewPager很不流暢,感覺很不爽,網上找了好久,試了各種解決方案都沒能解決問題,最后還是看了下PullToRefreshLayout的源碼,發現了PullableListView下拉和上拉是實現了canPullDown()和canPullUp()兩個接口,只要在這兩個方法里面返回false,就不可以上拉和下拉,所以添加一個boolean變量isCanPullDown來控制其滑動,代碼如下:

public class PullableListView extends ListView implements Pullable {

private boolean isCanPullDown = true;//是否允許滑動

public PullableListView(Context context) {
super(context);
}

public PullableListView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public PullableListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
public boolean canPullDown() {
if (isCanPullDown) {//是否允許滑動
if (getCount() == 0) {
// 沒有item的時候也可以下拉刷新
return true;
} else if (getFirstVisiblePosition() == 0
&& getChildAt(0).getTop() >= 0) {
// 滑到ListView的頂部了
return true;
} else
return false;
} else {
return false;
}
}

@Override
public boolean canPullUp() {
if (getCount() == 0) {
// 沒有item的時候也可以上拉加載
return true;
} else if (getLastVisiblePosition() == (getCount() - 1)) {
// 滑到底部了
if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null
&& getChildAt(
getLastVisiblePosition()
- getFirstVisiblePosition()).getBottom() <= getMeasuredHeight())
return true;
}
return false;
}

public void setCanPullDown(boolean canPullDown) {
isCanPullDown = canPullDown;
}
}
然后自定義類繼承VierPager,重寫dispatchTouchEvent方法,通過判斷滑動事件,如果是水平滑動,請求父類不要阻塞觸摸事件,並且通過PullableListView的剛剛添加的setCanPullDown(false)方法禁止下拉刷新,當滑動結束等其它情況時調用setCanPullDown(false)允許下拉刷新,OK,到此問題就這樣完美的解決了,是不是很簡單

    @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//記錄下按下時當前的xy左標
mDownX = ev.getX();
mDownY = ev.getY();
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
//滑動時計算x軸y軸的移動距離 ,如果x軸移動距離大於y軸,說明是水平滑動,禁止下拉刷新
if (Math.abs(ev.getX() - mDownX) > Math.abs(ev.getY() - mDownY)) {
getParent().requestDisallowInterceptTouchEvent(true);
((PullableListView) parentView).setCanPullDown(false);
} else {
getParent().requestDisallowInterceptTouchEvent(false);
((PullableListView) parentView).setCanPullDown(true);
}
break;
case MotionEvent.ACTION_CANCEL:
getParent().requestDisallowInterceptTouchEvent(false);
((PullableListView) parentView).setCanPullDown(true);
break;
case MotionEvent.ACTION_UP:
getParent().requestDisallowInterceptTouchEvent(false);
((PullableListView) parentView).setCanPullDown(true);
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}




注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com