在项目中使用了
android-Ultra-Pull-To-Refresh
组件实现下拉刷新,有个页面是在下拉刷新ListView中包含了一个ViewPager,因为ListView和ViewPager的事件冲突导致ViewPager左右滑动的时候非常难,这是个常见的问题,使用下面改造的ViewPager就能解决这个问题。
这段代码也很好理解,就是在处理ViewPager touch事件的时候把他的父组件的事件屏蔽掉,这样就只响应了ViewPager touch事件,其实主要是parent.requestDisallowInterceptTouchEvent(true);这句代码的作用,这个是android组件的约定,这个会一级一级的上传,让所有的父组件都不响应touch事件。
但是在android-Ultra-Pull-To-Refresh的PtrFrameLayout上使用上面改造的ViewPager却没有效果,查看PtrFrameLayout源码发现他在实现dispatchTouchEvent方法时,没有考虑到FLAG_DISALLOW_INTERCEPT的因素,导致requestDisallowInterceptTouchEvent方法不起作用。OK,找到了问题点那就改造下PtrFrameLayout好了, 如下:
继承PtrFrameLayout,当如果调用了requestDisallowInterceptTouchEvent方法,那么dispatchTouchEvent方法就调用dispatchTouchEventSupper,这个其实就是ViewGroup中dispatchTouchEvent的实现。 OK,使用这个FixRequestDisallowTouchEventPtrFrameLayout和DisallowParentTouchViewPager类, 就解决了android-Ultra-Pull-To-Refresh下拉刷新组件和ViewPager事件冲突的问题。
- package com.myzaker.autoinsurance.ui.view;
- import android.content.Context;
- import android.os.Debug;
- import android.support.v4.view.ViewPager;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.ViewGroup;
- /**
- * Created by Denny on 2015/8/1.
- */
- public class DisallowParentTouchViewPager extends ViewPager {
- private ViewGroup parent;
- public DisallowParentTouchViewPager(Context context) {
- super(context);
- }
- public DisallowParentTouchViewPager(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public void setNestParent(ViewGroup parent) {
- this.parent = parent;
- }
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (parent != null) {
- parent.requestDisallowInterceptTouchEvent(true);
- }
- return super.dispatchTouchEvent(ev);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (parent != null) {
- parent.requestDisallowInterceptTouchEvent(true);
- }
- return super.onInterceptTouchEvent(ev);
- }
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (parent != null) {
- parent.requestDisallowInterceptTouchEvent(true);
- }
- return super.onTouchEvent(ev);
- }
- }
这段代码也很好理解,就是在处理ViewPager touch事件的时候把他的父组件的事件屏蔽掉,这样就只响应了ViewPager touch事件,其实主要是parent.requestDisallowInterceptTouchEvent(true);这句代码的作用,这个是android组件的约定,这个会一级一级的上传,让所有的父组件都不响应touch事件。
但是在android-Ultra-Pull-To-Refresh的PtrFrameLayout上使用上面改造的ViewPager却没有效果,查看PtrFrameLayout源码发现他在实现dispatchTouchEvent方法时,没有考虑到FLAG_DISALLOW_INTERCEPT的因素,导致requestDisallowInterceptTouchEvent方法不起作用。OK,找到了问题点那就改造下PtrFrameLayout好了, 如下:
- package com.myzaker.autoinsurance.ui.view;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import in.srain.cube.views.ptr.PtrFrameLayout;
- /**
- * Created by Denny on 2015/8/1.
- */
- public class FixRequestDisallowTouchEventPtrFrameLayout extends PtrFrameLayout {
- private boolean disallowInterceptTouchEvent = false;
- public FixRequestDisallowTouchEventPtrFrameLayout(Context context) {
- super(context);
- }
- public FixRequestDisallowTouchEventPtrFrameLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public FixRequestDisallowTouchEventPtrFrameLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
- @Override
- public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
- disallowInterceptTouchEvent = disallowIntercept;
- super.requestDisallowInterceptTouchEvent(disallowIntercept);
- }
- @Override
- public boolean dispatchTouchEvent(MotionEvent e) {
- if (disallowInterceptTouchEvent) {
- return dispatchTouchEventSupper(e);
- }
- return super.dispatchTouchEvent(e);
- }
- }
继承PtrFrameLayout,当如果调用了requestDisallowInterceptTouchEvent方法,那么dispatchTouchEvent方法就调用dispatchTouchEventSupper,这个其实就是ViewGroup中dispatchTouchEvent的实现。 OK,使用这个FixRequestDisallowTouchEventPtrFrameLayout和DisallowParentTouchViewPager类, 就解决了android-Ultra-Pull-To-Refresh下拉刷新组件和ViewPager事件冲突的问题。