listview滑動衝突處理
阿新 • • 發佈:2018-11-05
在android中,有時候會遇到子控制元件和父控制元件都要滑動的情況,尤其是當子控制元件為listview的時候。這種情況較常見,典型的launcher,每個螢幕上放上listview就會出現這種情況。
當view的onTouchEvent返回true,即消耗點選事件,viewgroup的onInterceptTouchEvent返回false,即不攔截點選事件。但是listview的父類AbsListView重寫了onInterceptTouchEvent,返回了true,注意這裡不是一定返回true。
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;
}