close

有了上次 MotionLayout 的踩雷經驗

詳情請看下方連結

Android Kotlin 為什麼在 MotionLayout 中,用程式調用 setVisibility() View.GONE 無效。 Programmatically set visibility not working on MotionLayout』Willy's Fish教學筆記

 

這次就很容易聯想到是 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://medium.com/vrt-digital-studio/picture-in-picture-video-overlay-with-motionlayout-a9404663b9e7

 

 

參考資料:

https://developer.android.com/training/constraint-layout/motionlayout

 

 

 

 

 

 

 

 

 


arrow
arrow

    顏澤偉 發表在 痞客邦 留言(0) 人氣()