1. 程式人生 > >listview滑動衝突處理

listview滑動衝突處理

在android中,有時候會遇到子控制元件和父控制元件都要滑動的情況,尤其是當子控制元件為listview的時候。這種情況較常見,典型的launcher,每個螢幕上放上listview就會出現這種情況。

  1. 當view的onTouchEvent返回true,即消耗點選事件,viewgroup的onInterceptTouchEvent返回false,即不攔截點選事件。但是listview的父類AbsListView重寫了onInterceptTouchEvent,返回了true,注意這裡不是一定返回true。

  2. onTouchEvent和onInterceptTouchEvent的呼叫順序。點選事件從父控制元件向子控制元件傳遞,如果父控制元件不攔截,則交由子控制元件攔截,如果父控制元件攔截了,則交由父控制元件的onTouchEvent處理,如果最終處理點選事件的控制元件的onTouchEvent返回了false,則將會直接呼叫其父控制元件的onTouchEvent,如此向上類推。

解決方法:重寫父控制元件的onInterceptTouchEvent函式,在move的時候根據需要返回true,比如左右滑動返回true,其他情況均返回false。這樣,當左右滑動的時候,由於onInterceptTouchEvent返回了true,父控制元件就能處理,其他情況,事件將傳遞到listview中,listview自身可以處理上下滑動


//TouchSlop是系統所能識別出的被認為是滑動的最小距離,換個說法,當手指在螢幕上滑動時,如果兩次滑動之間的距離小於這個 常量,那麼系統就不認為你是在進行滑動操作。


@Override  
public boolean onInterceptTouchEvent
(MotionEvent ev) { Log.e("TAG", "onInterceptTouchEvent:"+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; }