言いたいことはそれだけか

KotlinとかAndroidとかが好きです。調べたことをメモします。٩( 'ω' )و

MotionLayoutでvisibilityを制御するときのメモ書き

MotionLayoutでvisibilityを制御するときにちょっと困ったのでメモを残す。

やりたいこと

  • あるイベント契機でアニメーションを表示する
    • イベントはコードからtrigger
    • アニメーションとして画像を画面中央から上部に動かす(Twitterのお誕生日の風船みたいな感じ)
  • アニメーションはMotionLayoutでstartとendを定義するが、startのタイミングでvisibilityをVISIBLEにしたい。

こうやれば動くよ

Layout定義

最低限のattributeだけ書く。残りはいい感じに補完すること。 アニメーションしたい画像のvisibilityはGONEにしておく。

<androidx.constraintlayout.motion.widget.MotionLayout
    android:id="@+id/motion_base"

    >

    <ImageView
        android:id="@+id/animation_image"
        android:visibility="gone"

    />
/>

MotionScene

ポイントはvisibilityの設定をLayoutタグの中ではなく、PropertySetの中に記載すること。ちなみにLayoutタグの中でvisibilityをVISIBLEにしてしまうとxml layout fileが読み込まれたタイミングでvisibilityがVISIBLEになってしまう。(Layoutタグの中は省略しているので適宜補完。)

<MotionScene 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint android:id="@+id/animation_image">
            <Layout
                android:layout_width="0dp"
                android:layout_height="wrap_content"/>
            <PropertySet
                android:visibility="visible"
                app:visibilityMode="ignore" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/animation_image"
            android:translationY="-300dp" />
    </ConstraintSet>
</MotionScene>

アニメーションをtriggerするコード

PropertySetでvisibilityを変更するのに加えて、アニメーションをtriggerする直前にコードでもvisibilityを変えてやらないとVISIBLEにならない。

findViewById<ImageView>(R.id.animation_image).visibility = View.VISIBLE
findViewById<MotionLayout>(R.id.motion_base).transitionToEnd()

言いたいことは以上です。