解決android-Ultra-Pull-To-Refresh 和ViewPager衝突的問題
阿新 • • 發佈:2018-12-19
由於PtrFrameLayout在dispatchOnTouchEvent中沒有判斷事件攔截的情況,導致PtrFrameLayout如果內部的content包含有ViewPager時會出現翻頁異常困難的情況,參考了網上的多的文章沒有解決,很多都是有bug的,今天在網上看到SwipeRefreshLayout 和Viewpager的衝突解決方法,參考了下 靈機一動,原文地址Android:SwipeRefreshLayout和ViewPager滑動衝突的原因,做了一些簡單的修改!希望可以幫到正在被這個問題困惑的朋友,謝謝!程式碼如下。
<pre name="code" class="java">package com.hengtiansoft.mob.ui.view; import android.content.Context; import android.support.v4.view.ViewConfigurationCompat; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.ViewConfiguration; import in.srain.cube.views.ptr.PtrClassicDefaultHeader; import in.srain.cube.views.ptr.PtrFrameLayout; public class PtrHTFrameLayout extends PtrFrameLayout { private PtrClassicDefaultHeader mPtrClassicHeader; private float startY; private float startX; // 記錄viewPager是否拖拽的標記 private boolean mIsHorizontalMove; // 記錄事件是否已被分發 private boolean isDeal; private ViewPager mViewPager; private int mTouchSlop; public PtrHTFrameLayout(Context context) { super(context); initViews(); } public PtrHTFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); initViews(); } public PtrHTFrameLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initViews(); } private void initViews() { mPtrClassicHeader = new PtrClassicDefaultHeader(getContext()); setHeaderView(mPtrClassicHeader); addPtrUIHandler(mPtrClassicHeader); } public PtrClassicDefaultHeader getHeader() { return mPtrClassicHeader; } /** * Specify the last update time by this key string * * @param key */ public void setLastUpdateTimeKey(String key) { if (mPtrClassicHeader != null) { mPtrClassicHeader.setLastUpdateTimeKey(key); } } /** * Using an object to specify the last update time. * * @param object */ public void setLastUpdateTimeRelateObject(Object object) { if (mPtrClassicHeader != null) { mPtrClassicHeader.setLastUpdateTimeRelateObject(object); } } /** * PtrHTFrameLayout has a viewpager * * @param viewPager */ public void setViewPager(ViewPager viewPager) { this.mViewPager = viewPager; if (mViewPager == null) { throw new IllegalArgumentException("viewPager can not be null"); } final ViewConfiguration configuration = ViewConfiguration.get(getContext()); mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (mViewPager == null) { return super.dispatchTouchEvent(ev); } int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // 記錄手指按下的位置 startY = ev.getY(); startX = ev.getX(); // 初始化標記 mIsHorizontalMove = false; isDeal = false; break; case MotionEvent.ACTION_MOVE: // 如果已經判斷出是否由橫向還是縱向處理,則跳出 if (isDeal) { break; } /**攔截禁止交給Ptr的 dispatchTouchEvent處理**/ mIsHorizontalMove = true; // 獲取當前手指位置 float endY = ev.getY(); float endX = ev.getX(); float distanceX = Math.abs(endX - startX); float distanceY = Math.abs(endY - startY); if (distanceX != distanceY) { // 如果X軸位移大於Y軸位移,那麼將事件交給viewPager處理。 if (distanceX > mTouchSlop && distanceX > distanceY) { mIsHorizontalMove = true; isDeal = true; } else if (distanceY > mTouchSlop) { mIsHorizontalMove = false; isDeal = true; } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: //下拉重新整理狀態時如果滾動了viewpager 此時mIsHorizontalMove為true 會導致PtrFrameLayout無法恢復原位 // 初始化標記, mIsHorizontalMove = false; isDeal = false; break; } if (mIsHorizontalMove) { return dispatchTouchEventSupper(ev); } return super.dispatchTouchEvent(ev); } }