转自 : http://blog.csdn.net/issingleman/article/details/51182209
由于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);
- }
- }