有了上次 MotionLayout 的踩雷經驗
詳情請看下方連結
這次就很容易聯想到是 MotionLayout 的關係了
本問題是「當 View 在 OnSwipe or OnClick 之後 setOnClickListener() 無效」
先來看看我們的佈局
<androidx.constraintlayout.motion.widget.MotionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/motionLayout"
android:layout_width="match_parent"
android:layout_height="96dp"
app:layoutDescription="@xml/item_scene">
<LinearLayout
android:id="@+id/itemLayout"
。。。>
</androidx.constraintlayout.motion.widget.MotionLayout>
然後 scene 是長這樣
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="500">
<OnSwipe
app:dragDirection="dragLeft"
app:onTouchUp="autoComplete"
app:touchAnchorId="@id/itemLayout" />
</Transition>
可以看到,我們有一個 MotionLayout 包著一個 itemLayout
然後我們設定 OnSwipe 當拖移 itemLayout 的時候
執行場景轉換
不過因為 itemLayout 也有被點擊的需求
本來想說 MotionLayout 吃的是拖移手勢
所以很直覺的就給 itemLayout 一個 OnClickListener
想當然會吃不到手勢
我們把 log 印出來看看
itemLayout.setOnTouchListener { v, event ->
PLog.d("item start")
when(event.action){
MotionEvent.ACTION_DOWN -> PLog.d("down")
MotionEvent.ACTION_MOVE -> PLog.d("move")
MotionEvent.ACTION_UP -> PLog.d("up")
}
。。。
}
這樣的話,每當我們對 itemLayout 做任何手勢
都會出現下列結果
item start
down
結束 !!!
疑,我們的手勢只有一個 down ?
沒錯,我猜測其它的都被 MotionLayout 抓走了
所以我們再加印一些 log 看看
motionLayout.setOnTouchListener { v, event ->
PLog.d("m start")
when(event.action){
MotionEvent.ACTION_DOWN -> PLog.d("m down")
MotionEvent.ACTION_MOVE -> PLog.d("m move")
MotionEvent.ACTION_UP -> PLog.d("m up")
}
。。。
}
這次我們做拖移的結果會如下
item start
down
m start
m down
m start
m move
m start
m move
m start
m up
結束 !!!
兇手已經抓到了
那我們該怎麼解決這個問題呢?
因為我這次的 UI 比較單純
所以我是直接在 MotionLayout 的 OnTouchListener 中做事情
若是有需求的朋友,建議採取另一個方式
自訂 MotionLayout
這裡有一位範例,可以給大家參考
希望大家順利 !!!
參考資料:
https://developer.android.com/training/constraint-layout/motionlayout
留言列表