ViewFlow嵌套在ViewPager事件冲突的解决

最近看上了网易新闻的主页模式,于是乎,我就照着做了。


其实本质就是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滑动冲突的问题。

你可能感兴趣的:(ViewFlow嵌套在ViewPager事件冲突的解决)