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;
	}
相關文章
相關標籤/搜索