美文网首页Android
Android-Ultra-Pull-To-Refresh刷新框

Android-Ultra-Pull-To-Refresh刷新框

作者: 啸林 | 来源:发表于2016-12-24 14:33 被阅读993次

    文章概述:

    本篇文章记录,解决github上开源框架android-Ultra-Pull-To-Refresh内嵌套viewpager的滑动冲突问题。

    问题描述:

    liaohuqiu 开源的 android-Ultra-Pull-To-Refresh 下拉刷新框架,在使用时,会经常遇到嵌套banner的使用场景,即:子ViewGroup嵌套ViewPager使用,例如:

    <com.vic.bmar.widgets.PtrClassicRefreshLayout
        android:id="@+id/pcfl_hot"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/grey_color"
            android:scrollbars="none">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                
                <!-- 这里的FrameLayout用作放ViewPager的容器 -->
                <FrameLayout
                    android:id="@+id/banner"
                    android:layout_width="match_parent"
                    android:layout_height="160dp"/>
            </LinearLayout>
        </android.support.v4.widget.NestedScrollView>
    </com.vic.bmar.widgets.PtrClassicRefreshLayout>
                    
    

    PtrClassicRefreshLayout是PtrFrameLayout的子类,默认实现了头部刷 新时的样式,可以直接拿来使用。

    这时候会与ViewPager发生滑动冲突,ViewPager左右很难滑动,作者已经给出了一种解决方法:

    //左右滑动时刷新控件禁止掉
    pcflFrameLayout.disableWhenHorizontalMove(true);
    

    这样做ViewPager可以左右滑动了,但是左右滑动有时还是不好滑动,并且,ViewPager滑动时经常会触发PtrFrameLayout的刷新样式,用户体验很差。

    解决方案

    1. 重写ViewPager

    public class BannerViewPager extends ViewPager {
    
        private ViewGroup parent;
    
        public BannerViewPager(Context context) {
            super(context);
            parent= (ViewGroup) getParent();
        }
    
        public BannerViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
            parent= (ViewGroup) getParent();
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            int action = ev.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    if (parent != null) {
                        //禁止上一层的View不处理该事件,屏蔽父组件的事件
                        parent.requestDisallowInterceptTouchEvent(true);
                    }
                    break;
                case MotionEvent.ACTION_CANCEL:
                    if (parent != null) {
                        //拦截
                        parent.requestDisallowInterceptTouchEvent(false);
                    }
                    break;
    
                default:
                    break;
            }
            return super.dispatchTouchEvent(ev);
        }
    }
    

    2. 重写PtrClassicRefreshLayout

    这里为了方便,就不自定义刷新样式,直接使用PtrClassicRefreshLayout刷新样式,如果想重写刷新样式,可以继承PtrFrameLayout。

    public class PtrClassicRefreshLayout extends PtrClassicFrameLayout {
        private boolean disallowInterceptTouchEvent = false;
    
        public PtrClassicRefreshLayout(Context context) {
            super(context);
        }
    
        public PtrClassicRefreshLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public PtrClassicRefreshLayout(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) {
            switch (e.getAction()) {
                case MotionEvent.ACTION_UP:
                    //解除刷新的屏蔽
                    this.requestDisallowInterceptTouchEvent(false);
                    break;
            }
    
            if (disallowInterceptTouchEvent) {
                //事件向下分发给子控件,子控件会屏蔽掉父控件的刷新
                return dispatchTouchEventSupper(e);
            }
    
            return super.dispatchTouchEvent(e);
        }
    }
    

    直接copy这两个自定义组件的代码使用,再加上作者推荐的设置:

    pcflFrameLayout.disableWhenHorizontalMove(true);

    即可解决android-Ultra-Pull-To-Refresh下拉刷新框架与viewpager使用冲突问题.

    相关文章

      网友评论

        本文标题:Android-Ultra-Pull-To-Refresh刷新框

        本文链接:https://www.haomeiwen.com/subject/qiglvttx.html