在我们平时的开发中一般是不推荐ScrollView中再嵌套ListView,ViewPager等其他可滑动组件的(至少Google是不推荐我们这样做的),但是为了实现一些特殊的需求,我们又不得不这样做,像一些知名的APP都有这样的先例,那他们是怎么做到的呢.
最近由于项目需要,需要展示公司所有的产品目录,一级目录只有27个,可美工为了视觉的美观,将27个一级目录分为了三个组,每组中又有三屏可以滑动,为了这个需求,就不得不在ScrollView中嵌套ViewPager了,我目前只有这个思路,等我将界面绘制出来后,发现ViewPager几乎是滑不动的,要想滑起来特别困难,这样的用户体验太差了,第一时间想到了事件冲突,ScrollView拦截到事件后要处理,就导致ViewPager滑起来非常的吃力,上网查阅后也没有相关的现成的方法,只好自己苦想了.
有了需求以后,我们就着手开始编写程序了,下面是我对ViewPager的一个重写:
先看下效果图:
这样就会有即上下滑动又左右滑动的情况出现
public class HomeBannerViewPager extends ViewPager {
private int timerIndex = 0;
private int currentPositon = 0;
private boolean flag = true;
private float mLastMotionY;
private float mLastMotionX;
public HomeBannerViewPager(Context context) {
super(context);
}
public HomeBannerViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final float x = ev.getX();
final float y = ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
setPullToScrollViewStatus(true);
flag = true;
mLastMotionX = x;
mLastMotionY = y;
mHandler.sendEmptyMessage(1);
break;
case MotionEvent.ACTION_MOVE:
if (flag) {
if (Math.abs(y - mLastMotionY) > Util.dip2px(20)
&& Math.abs(x - mLastMotionX) < Util.dip2px(5)) {
flag = false;
setPullToScrollViewStatus(false);
}
}
break;
case MotionEvent.ACTION_UP:
setPullToScrollViewStatus(false);
mHandler.sendEmptyMessage(0);
break;
case MotionEvent.ACTION_CANCEL:
setPullToScrollViewStatus(false);
mHandler.sendEmptyMessage(0);
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
/**
* ������ҳ����ScrollView�ؼ���״̬�������Banner�����¼���ͻ
*
* @param disallowIntercept
*/
private void setPullToScrollViewStatus(boolean disallowIntercept) {
getParent().getParent().getParent()
.requestDisallowInterceptTouchEvent(disallowIntercept);
}