最近看上了网易新闻的主页模式,于是乎,我就照着做了。
其实本质就是ViewPager嵌入多个listview左右滑动,然后在每个ListView顶部加上一个小的ViewPager去自动滚动展示图片。
于是乎,我想到了用ViewFlow、但是理想很丰满,现实很骨感。嵌套进来以后就发现,左右滑动的事件处理发生了冲突。无论如何左右滑动,生效的总是最外层的ViewPager,而不是内层的ViewFlow。再于是乎,我请教了晓阳大神,他给了我一个思路,那就是,复写ViewFlow的onTouchEvent(MotionEvent ev)方法,来告知何时不让ViewPager处理滑动事件何时处理。
解决方法的核心就是ViewGroup里的两个个方法。
onInterceptTouchEvent()
;
requestDisallowInterceptTouchEvent()
;
以下是android官网的对这两个个方法的一个说明:http://developer.android.com/training/gestures/viewgroup.html
说明里面其中有一段这么说的
Note that ViewGroup
also provides arequestDisallowInterceptTouchEvent()
method. TheViewGroup
calls this method when a child does not want the parent and its ancestors to intercept touch events withonInterceptTouchEvent()
.
意思是说要注意ViewGroup也提供了一个requestDisallowInterceptTouchEvent()
方法。当一个子控件不希望父控件去用onInterceptTouchEvent()
插入触控事件处理,ViewGroup就可以调用这个方法。
ViewFlow作为ViewPager的一个子控件,何时让父控件处理何时不让父控件处理呢?
我们只要让手指在ViewFlow上的时候不让ViewPager处理事件就可以了。
于是乎,我就继承了ViewFlow,复写了onInterceptTouchEvent()
方法,当插入触控事件之初就开始告诉父控件。其实复写onTouchEvent()方法也可以,但是效果不如前者更好。
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (getContext() instanceof MainActivity) {
MainActivity m = (MainActivity) getContext();
m.mPager.requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_UP:
if (getContext() instanceof MainActivity) {
MainActivity m = (MainActivity) getContext();
m.mPager.requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_CANCEL:
if (getContext() instanceof MainActivity) {
MainActivity m = (MainActivity) getContext();
m.mPager.requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_MOVE:
if (getContext() instanceof MainActivity) {
MainActivity m = (MainActivity) getContext();
m.mPager.requestDisallowInterceptTouchEvent(true);
}
break;
}
return super.onInterceptTouchEvent(ev);
}
注意 ,m.mPager是我把MainActivity里的Viewpager从页面上的实例公开出来使用的。这里要调用viewpager里的requestDisallowInterceptTouchEvent()
方法,通过调用ViewPager的requestDisallowInterceptTouchEvent()
方法告诉ViewPager在我触摸到ViewFlow的时候MotionEvent.ACTION_DOWN和移动MontionEvent.ACTION_MOVE的时候,不允许插入触控事件的处理。而在MotionEvent.ACTION_CANCEL和MotionEvent.ACTION_UP放开ViewPager的插入事件处理。
用继承后的ViewFlow去作为ViewPager,就可以完美解决ViewPager和ViewFlow滑动冲突的问题。