listview所带来的滑动冲突

在android中,有时候会遇到子控件和父控件都要滑动的状况,尤为是当子控件为listview的时候。这种状况较常见,典型的launcher,每一个屏幕上放上listview就会出现这种状况。java

有两点须要注意:android

  1. 通常来讲,view的onTouchEvent返回true,即消耗点击事件,viewgroup的onInterceptTouchEvent返回false,即不拦截点击事件,这一点从android源码中能够看出来。可是listview的父类AbsListView重写了onInterceptTouchEvent,返回了true,注意这里不是必定返回true,可是我以为这一点能够先忽略。
  2. onTouchEvent和onInterceptTouchEvent的调用顺序。点击事件从父控件向子控件传递,若是父控件不拦截,则交由子控件拦截,若是父控件拦截了,则交由父控件的onTouchEvent处理,若是最终处理点击事件的控件的onTouchEvent返回了false,则将会直接调用其父控件的onTouchEvent,如此向上类推。

其实解决方法也很简单:重写父控件的onInterceptTouchEvent函数,在move的时候根据须要返回true,好比左右滑动返回true,其余状况均返回false。这样,当左右滑动的时候,因为onInterceptTouchEvent返回了true,父控件就能处理,其余状况,事件将传递到listview中,listview自身能够处理上下滑动。ide

@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) 
	{
		Log.d(TAG, "onInterceptTouchEvent-slop:"+mTouchSlop);

		final int action = ev.getAction();
		if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST))
		{
			return true;
		}

		final float x = ev.getX();
		final float y = ev.getY();

		switch (action)
		{
		case MotionEvent.ACTION_MOVE:
			final int xDiff = (int)Math.abs(mLastMotionX-x);
			if (xDiff>mTouchSlop)
			{
				mTouchState = TOUCH_STATE_SCROLLING;
			}
			break;

		case MotionEvent.ACTION_DOWN:
			mLastMotionX = x;
			mLastMotionY = y;
			mTouchState = mScroller.isFinished()? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
			break;

		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:
			mTouchState = TOUCH_STATE_REST;
			break;
		}

		return mTouchState != TOUCH_STATE_REST;
	}
相关文章
相关标签/搜索