[Android/Kotlin] MotionLayout

MotionLayout이란?

MotionLayout는 앱에서 모션과 위젯 애니메이션을 관리하는 데 도움이 되는 레이아웃.

ConstaintLayout의 서브클래스이다.

MotionLayout은 완전히 선언적이므로, XML에서 모든 전환을 설명할 수 있다.

간단한 스와이핑 애니메이션 만들기

오늘 만들 것

주의사항

https://developer.android.com/develop/ui/views/animations/motionlayout?hl=ko#androidx

공식 문서에 따르면, 사용자가 상호작용 하는 버튼, 제목 표시줄 등 UI 요소를 이동하고 크기를 조절 및 애니메이션 처리를 위한 것이다. 불필요한 특수효과로는 사용하지 말라고 한다.

사용해보기

의존성 추가하기

dependencies {
    implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha07"
    implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha07"
}

MotionLayout 파일 만들기

처음에 설명했던 것 처럼 MotionLayoutConstraintLayout의 서브클래스 이므로, 기존의 ContraintLayoutMotionLayout으로 변환하여 사용이 가능하다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout 
        xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/activity_main_scene"
    app:showPaths="true">
    <View
        android:id="@+id/button"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:background="@color/material_dynamic_neutral50"
        android:text="Button" />
</androidx.constraintlayout.motion.widget.MotionLayout>

기본적인 소스코드이다.

각각의 소스코드에 대한 간단한 설명을 진행하면,

showPaths의 경우에는 애니메이션의 경로를 시각적으로 표시할 것인지에 대한 여부이다. 기본값은 false이다.

layoutDescription는 모션 장면을 참조하는데, 여기서 모션 장면이란 XML 리소스 파일이다. 별도의 MotionScene 파일 내의 상응하는 레이아웃의 설명이 포함이 된다.

MotionScene 파일

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

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/end"
        motion:duration="1000">
        <OnSwipe
            motion:touchAnchorId="@+id/button"
            motion:touchAnchorSide="right"
            motion:dragDirection="dragRight" />
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginStart="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="backgroundColor"
                motion:customColorValue="#D81B60" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginEnd="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="backgroundColor"
                motion:customColorValue="#9999FF" />
        </Constraint>
    </ConstraintSet>

</MotionScene>

해당 MotionScene 파일의 경우에는 , 왼쪽에서 오른쪽으로 스와이프 시 애니메이션을 정의한 파일이다.

Transition을 통해 startend 사이의 전환을 duration을 1초로 설정을 하였다.

ConstraintSet의 경우에는 애니메이션 시작 시 버튼의 위치와 속성을 정의했다.

startend 두 경우로 나뉘어 작성 하였으며, 시작의 경우에는 왼쪽, 종료 시점은 오른쪽으로 정의하였다. 각각의 배경색 또한 다르게 지정하였다.