Android事件沖突處理方案無非兩種:內(nèi)部攔截法和外部攔截法
外部攔截法偽代碼:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//外部攔截法
boolean intercept = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
intercept = false;
break;
case MotionEvent.ACTION_MOVE:
if (父容器需要事件) {
intercept = true;
} else {
intercept = false;
}
break;
case MotionEvent.ACTION_UP:
intercept = false;
break;
default:
break;
}
return intercept;
}
內(nèi)部攔截法偽代碼:
主要通過requestDisallowInterceptTouchEvent(),該方法可以讓父 view的事件攔截生效脸哀,那么如果父View的攔截失效宴抚,則子View即可獲得事件
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
if (父容器需要事件){
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}
由于父容器的down事件不受requestDisallowInterceptTouchEvent()影響(因為在down事件攔截前會執(zhí)行重置操作)商源,而down事件如果被父容器攔截,則后續(xù)事件都由父容器處理鸯旁,因此需要在父容器的事件攔截中實現(xiàn)如下代碼才能完成內(nèi)部攔截法的全過程
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//內(nèi)部攔截法
if (ev.getAction() == MotionEvent.ACTION_DOWN){
return false;
}
return true;
}
接下來我們通過一個例子來演示事件沖突的處理,該例子中就是父容器ScrollView中嵌套了ListView,同方向的滑動沖突泣港,布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ScrollView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@color/purple_200"
android:text="textView1"
android:textColor="@color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@color/purple_700"
android:text="textView2"
android:textColor="@color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@color/purple_200"
android:text="textView1"
android:textColor="@color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@color/purple_700"
android:text="textView2"
android:textColor="@color/white" />
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:layout_width="match_parent"
android:layout_height="250dp"
android:background="@color/purple_200"
android:text="textView1"
android:textColor="@color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@color/purple_700"
android:text="textView2"
android:textColor="@color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@color/purple_200"
android:text="textView1"
android:textColor="@color/white" />
<TextView
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="@color/purple_700"
android:text="textView2"
android:textColor="@color/white" />
</LinearLayout>
</ScrollView>
</android.support.constraint.ConstraintLayout>
在不處理滑動沖突時暂殖,效果如下,ScrollView可以滑動当纱,ListView不能滑動
未命名-副本.gif