Android

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

2016-12-24  本文已影响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使用冲突问题.

上一篇下一篇

猜你喜欢

热点阅读