文章概述:
本篇文章记录,解决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使用冲突问题.
网友评论