解决android-Ultra-Pull-To-Refresh 和ViewPager冲突的问题

来源:互联网 发布:数据库sql中select语句 编辑:程序博客网 时间:2024/09/21 08:17

转自 : http://blog.csdn.net/issingleman/article/details/51182209


由于PtrFrameLayout在dispatchOnTouchEvent中没有判断事件拦截的情况,导致PtrFrameLayout如果内部的content包含有ViewPager时会出现翻页异常困难的情况,参考了网上的多的文章没有解决,很多都是有bug的,今天在网上看到SwipeRefreshLayout 和Viewpager的冲突解决方法,参考了下 灵机一动,原文地址Android:SwipeRefreshLayout和ViewPager滑动冲突的原因,做了一些简单的修改!希望可以帮到正在被这个问题困惑的朋友,谢谢!代码如下。

[java] view plain copy
  1. <pre name="code" class="java">package com.hengtiansoft.mob.ui.view;  
  2.   
  3. import android.content.Context;  
  4. import android.support.v4.view.ViewConfigurationCompat;  
  5. import android.support.v4.view.ViewPager;  
  6. import android.util.AttributeSet;  
  7. import android.view.MotionEvent;  
  8. import android.view.ViewConfiguration;  
  9.   
  10. import in.srain.cube.views.ptr.PtrClassicDefaultHeader;  
  11. import in.srain.cube.views.ptr.PtrFrameLayout;  
  12.   
  13. public class PtrHTFrameLayout extends PtrFrameLayout {  
  14.     private PtrClassicDefaultHeader mPtrClassicHeader;  
  15.     private float startY;  
  16.     private float startX;  
  17.     // 记录viewPager是否拖拽的标记  
  18.     private boolean mIsHorizontalMove;  
  19.     // 记录事件是否已被分发  
  20.     private boolean isDeal;  
  21.     private ViewPager mViewPager;  
  22.     private int mTouchSlop;  
  23.     public PtrHTFrameLayout(Context context) {  
  24.         super(context);  
  25.         initViews();  
  26.     }  
  27.   
  28.     public PtrHTFrameLayout(Context context, AttributeSet attrs) {  
  29.         super(context, attrs);  
  30.         initViews();  
  31.     }  
  32.   
  33.     public PtrHTFrameLayout(Context context, AttributeSet attrs, int defStyle) {  
  34.         super(context, attrs, defStyle);  
  35.         initViews();  
  36.     }  
  37.   
  38.     private void initViews() {  
  39.         mPtrClassicHeader = new PtrClassicDefaultHeader(getContext());  
  40.         setHeaderView(mPtrClassicHeader);  
  41.         addPtrUIHandler(mPtrClassicHeader);  
  42.     }  
  43.   
  44.     public PtrClassicDefaultHeader getHeader() {  
  45.         return mPtrClassicHeader;  
  46.     }  
  47.   
  48.     /** 
  49.      * Specify the last update time by this key string 
  50.      * 
  51.      * @param key 
  52.      */  
  53.     public void setLastUpdateTimeKey(String key) {  
  54.         if (mPtrClassicHeader != null) {  
  55.             mPtrClassicHeader.setLastUpdateTimeKey(key);  
  56.         }  
  57.     }  
  58.   
  59.     /** 
  60.      * Using an object to specify the last update time. 
  61.      * 
  62.      * @param object 
  63.      */  
  64.     public void setLastUpdateTimeRelateObject(Object object) {  
  65.         if (mPtrClassicHeader != null) {  
  66.             mPtrClassicHeader.setLastUpdateTimeRelateObject(object);  
  67.         }  
  68.     }  
  69.   
  70.     /** 
  71.      * PtrHTFrameLayout has a viewpager 
  72.      * 
  73.      * @param viewPager 
  74.      */  
  75.     public void setViewPager(ViewPager viewPager) {  
  76.         this.mViewPager = viewPager;  
  77.         if (mViewPager == null) {  
  78.             throw new IllegalArgumentException("viewPager can not be null");  
  79.         }  
  80.         final ViewConfiguration configuration = ViewConfiguration.get(getContext());  
  81.         mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);  
  82.     }  
  83.     @Override  
  84.     public boolean dispatchTouchEvent(MotionEvent ev) {  
  85.         if (mViewPager == null) {  
  86.             return super.dispatchTouchEvent(ev);  
  87.         }  
  88.         int action = ev.getAction();  
  89.         switch (action) {  
  90.             case MotionEvent.ACTION_DOWN:  
  91.                 // 记录手指按下的位置  
  92.                 startY = ev.getY();  
  93.                 startX = ev.getX();  
  94.                 // 初始化标记  
  95.                 mIsHorizontalMove = false;  
  96.                 isDeal = false;  
  97.                 break;  
  98.             case MotionEvent.ACTION_MOVE:  
  99.                 // 如果已经判断出是否由横向还是纵向处理,则跳出  
  100.                 if (isDeal) {  
  101.                     break;  
  102.                 }  
  103.                 /**拦截禁止交给Ptr的 dispatchTouchEvent处理**/  
  104.                 mIsHorizontalMove = true;  
  105.                 // 获取当前手指位置  
  106.                 float endY = ev.getY();  
  107.                 float endX = ev.getX();  
  108.                 float distanceX = Math.abs(endX - startX);  
  109.                 float distanceY = Math.abs(endY - startY);  
  110.                 if (distanceX != distanceY) {  
  111.                     // 如果X轴位移大于Y轴位移,那么将事件交给viewPager处理。  
  112.                     if (distanceX > mTouchSlop && distanceX > distanceY) {  
  113.                         mIsHorizontalMove = true;  
  114.                         isDeal = true;  
  115.                     } else if (distanceY > mTouchSlop) {  
  116.                         mIsHorizontalMove = false;  
  117.                         isDeal = true;  
  118.                     }  
  119.                 }  
  120.                 break;  
  121.             case MotionEvent.ACTION_UP:  
  122.             case MotionEvent.ACTION_CANCEL:  
  123.                 //下拉刷新状态时如果滚动了viewpager 此时mIsHorizontalMove为true 会导致PtrFrameLayout无法恢复原位  
  124.                 // 初始化标记,  
  125.                 mIsHorizontalMove = false;  
  126.                 isDeal = false;  
  127.                 break;  
  128.         }  
  129.         if (mIsHorizontalMove) {  
  130.             return dispatchTouchEventSupper(ev);  
  131.         }  
  132.         return super.dispatchTouchEvent(ev);  
  133.     }  
  134. }  


0 0
原创粉丝点击