4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MotionLayoutで元のVisibilityを保持したままアニメーションを実行する

Last updated at Posted at 2020-08-23

はじめに

MotionLayoutは手軽にアニメーションを管理出来てとても便利なんですが、デフォルトの動作だと元のvisibilityを無視してアニメーションを実行するとViewが表示されてしまいます。こんな感じ↓
ですが、利用する際はINVISIBLEやGONEの場合はその非表示の状態を維持したままアニメーションさせたい場合がほとんどだと思いますので、今回はそのやり方を説明します。

やり方

修正前のコード

まず前述の修正前のアニメーションはこのようなコードで実装されています。

app/build.gradle
    // NOTE: MotionLayoutを利用するにはconstraintlayout:2.0.0以上を利用します
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // NOTE: アニメーションを開始
        hello1.setOnClickListener {
            if (motion.currentState == R.id.start) {
                motion.transitionToEnd()
            }else {
                motion.transitionToStart()
            }
        }

        // NOTE: 非表示にする
        hello2.setOnClickListener {
            it.visibility = View.INVISIBLE
        }
    }
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <androidx.constraintlayout.motion.widget.MotionLayout
        android:id="@+id/motion"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layoutDescription="@xml/hello_motion_scene">
        <TextView
            android:id="@+id/hello1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World! 1"
            />
        <TextView
            android:id="@+id/hello2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World! 2"
            />
    </androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
xml/hello_motion_scene.xml
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/hello1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toStartOf="@id/hello2"
            />
        <Constraint
            android:id="@+id/hello2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toEndOf="@id/hello1"
            app:layout_constraintEnd_toEndOf="parent"
            />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/hello1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@id/hello2"
            app:layout_constraintStart_toStartOf="parent"
            android:layout_marginBottom="50dp"
            />
        <Constraint
            android:id="@+id/hello2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@id/hello1"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginBottom="50dp"
            />
    </ConstraintSet>

    <Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@+id/start"
        app:duration="600"
        />
</MotionScene>

修正後のコード

visibilityを保持したコードにする場合は app:visibilityMode="ignore" を追加してあげるだけ。

xml/hello_motion_scene.xml
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/hello1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toStartOf="@id/hello2"
            app:visibilityMode="ignore"
            />
        <Constraint
            android:id="@+id/hello2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="50dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toEndOf="@id/hello1"
            app:layout_constraintEnd_toEndOf="parent"
            app:visibilityMode="ignore"
            />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/hello1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@id/hello2"
            app:layout_constraintStart_toStartOf="parent"
            android:layout_marginBottom="50dp"
            app:visibilityMode="ignore"
            />
        <Constraint
            android:id="@+id/hello2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@id/hello1"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginBottom="50dp"
            app:visibilityMode="ignore"
            />
    </ConstraintSet>

    <Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@+id/start"
        app:duration="600"
        />
</MotionScene>

これでアニメーション実行後に勝手に表示されることなく、visibilityを制御できるようになりました!

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?