MotionLayout
는 앱에서 모션과 위젯 애니메이션을 관리하는 데 도움이 되는 레이아웃 유형입니다. MotionLayout
는 ConstraintLayout
의 서브클래스이며 풍부한 레이아웃 기능을 기반으로 합니다. ConstraintLayout
라이브러리의 일부로 MotionLayout
를 지원 라이브러리로 사용할 수 있습니다.
MotionLayout
는 레이아웃 전환과 복잡한 모션 처리 간의 격차를 줄여 속성 애니메이션 프레임워크, TransitionManager
및 CoordinatorLayout
간의 혼합 기능을 제공합니다.
레이아웃 간의 전환을 설명하는 것 외에도 MotionLayout
를 사용하면 모든 레이아웃 속성에 애니메이션을 적용할 수 있습니다. 또한 기본적으로 검색 가능한 전환을 지원합니다. 즉, 터치 입력과 같은 일부 조건에 따라 전환 내의 원하는 지점을 즉시 표시할 수 있습니다. MotionLayout
는 키프레임도 지원하므로 필요에 맞게 완전히 맞춤설정된 전환을 사용할 수 있습니다.
MotionLayout
는 완전히 선언적입니다. 즉, 아무리 복잡하더라도 XML에서 모든 전환을 설명할 수 있습니다.
설계 고려사항
MotionLayout
는 사용자가 상호작용하는 버튼, 제목 표시줄 등 UI 요소를 이동하고 크기를 조절하고 애니메이션 처리하기 위한 것입니다. 앱에서 모션을 불필요한 특수 효과로 사용하지 마세요. 이를 통해 사용자가 앱의 기능을 이해할 수 있도록 도와주세요. 모션을 사용하여 앱을 디자인하는 방법에 관한 자세한 내용은 Material Design 섹션 모션 이해를 참고하세요.
시작하기
프로젝트에서 MotionLayout
사용을 시작하려면 다음 단계를 따르세요.
-
ConstraintLayout
종속 항목 추가: 프로젝트에서MotionLayout
를 사용하려면 앱의build.gradle
파일에ConstraintLayout
2.0 종속 항목을 추가합니다. AndroidX를 사용하는 경우 다음 종속 항목을 추가합니다.Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-alpha13" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha13") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-alpha13") }
-
MotionLayout
파일 만들기:MotionLayout
는ConstraintLayout
의 서브클래스이므로 다음 예와 같이 레이아웃 리소스 파일에서 클래스 이름을 바꿔 기존ConstraintLayout
를MotionLayout
로 변환할 수 있습니다.AndroidX
<!-- before: ConstraintLayout --> <androidx.constraintlayout.widget.ConstraintLayout .../> <!-- after: MotionLayout --> <androidx.constraintlayout.motion.widget.MotionLayout .../>
지원 라이브러리
<!-- before: ConstraintLayout --> <android.support.constraint.ConstraintLayout .../> <!-- after: MotionLayout --> <android.support.constraint.motion.MotionLayout .../>
다음은 그림 1에 표시된 레이아웃을 정의하는
MotionLayout
파일의 전체 예입니다.AndroidX
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <androidx.constraintlayout.motion.widget.MotionLayout 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:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </androidx.constraintlayout.motion.widget.MotionLayout>
지원 라이브러리
<?xml version="1.0" encoding="utf-8"?> <!-- activity_main.xml --> <android.support.constraint.motion.MotionLayout 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:id="@+id/motionLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layoutDescription="@xml/scene_01" tools:showPaths="true"> <View android:id="@+id/button" android:layout_width="64dp" android:layout_height="64dp" android:background="@color/colorAccent" android:text="Button" /> </android.support.constraint.motion.MotionLayout>
-
MotionScene 만들기: 이전
MotionLayout
예에서app:layoutDescription
속성은 모션 장면을 참조합니다. 모션 장면은 XML 리소스 파일입니다.<MotionScene>
루트 요소 내의 모션 장면에는 상응하는 레이아웃의 모든 모션 설명이 포함됩니다. 레이아웃 정보를 모션 설명과 별도로 유지하기 위해 각MotionLayout
는 별도의 모션 장면을 참조합니다. 모션 장면의 정의는MotionLayout
의 유사한 정의보다 우선합니다.다음은 그림 1의 기본 수평 모션을 설명하는 모션 장면 파일의 예입니다.
<?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" /> </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" /> </ConstraintSet> </MotionScene>
다음 내용을 참고하세요.
-
<Transition>
에는 모션의 기본 정의가 포함됩니다.-
motion:constraintSetStart
및motion:constraintSetEnd
는 모션의 엔드포인트 참조입니다. 이러한 엔드포인트는 모션 장면 후반부의<ConstraintSet>
요소에 정의됩니다. -
motion:duration
는 모션이 완료되는 데 걸리는 시간(밀리초)을 지정합니다.
-
-
<OnSwipe>
를 사용하면 모션의 터치 컨트롤을 만들 수 있습니다.-
motion:touchAnchorId
는 사용자가 스와이프하고 드래그할 수 있는 뷰를 나타냅니다. -
motion:touchAnchorSide
은 뷰가 오른쪽에서 드래그되고 있음을 의미합니다. -
motion:dragDirection
는 드래그의 진행 방향을 나타냅니다. 예를 들어motion:dragDirection="dragRight"
는 뷰를 오른쪽으로 드래그하면 진행률이 증가한다는 의미입니다.
-
-
<ConstraintSet>
에서는 모션을 설명하는 다양한 제약 조건을 정의합니다. 이 예에서는 모션의 각 엔드포인트에 하나의<ConstraintSet>
가 정의되어 있습니다. 이러한 엔드포인트는app:layout_constraintTop_toTopOf="parent"
및app:layout_constraintBottom_toBottomOf="parent"
를 사용하여 세로로 가운데에 배치됩니다. 가로로 봤을 때 엔드포인트는 화면의 맨 왼쪽과 오른쪽에 있습니다.
모션 장면에서 지원하는 다양한 요소에 관한 자세한 내용은 MotionLayout 예를 참고하세요.
-
보간된 속성
모션 장면 파일 내 ConstraintSet
요소에는 전환 중에 보간되는 추가 속성이 포함될 수 있습니다. 위치 및 경계 외에도 다음 속성이 MotionLayout
로 보간됩니다.
alpha
visibility
elevation
rotation
,rotationX
,rotationY
translationZ
translationY
translationX
scaleY
scaleX
맞춤 속성
<Constraint>
내에서 <CustomAttribute>
요소를 사용하여 위치 또는 View
속성과 관련 없는 속성의 전환을 지정할 수 있습니다.
<Constraint android:id="@+id/button" ...> <CustomAttribute motion:attributeName="backgroundColor" motion:customColorValue="#D81B60"/> </Constraint>
<CustomAttribute>
에는 다음과 같은 두 가지 고유 속성이 있습니다.
motion:attributeName
는 필수 항목이며 getter 및 setter 메서드가 있는 객체와 일치해야 합니다. getter와 setter는 특정 패턴과 일치해야 합니다. 예를 들어 뷰에 기본getBackgroundColor()
및setBackgroundColor()
메서드가 있으므로backgroundColor
가 지원됩니다.- 입력해야 하는 다른 속성은 값 유형을 기반으로 합니다. 지원되는 다음 유형 중에서 선택합니다.
motion:customColorValue
- 색상motion:customIntegerValue
- 정수motion:customFloatValue
- 부동수motion:customStringValue
- 문자열motion:customDimension
- 측정기준motion:customBoolean
- 부울
맞춤 속성을 지정할 때는 시작 및 끝 <ConstraintSet>
요소 모두에서 엔드포인트 값을 정의합니다.
배경 색상 변경
이전 예를 기반으로 그림 2와 같이 뷰의 모션에 따라 뷰의 색상을 변경하려고 한다고 가정해 보겠습니다.
다음 코드 스니펫과 같이 각 ConstraintSet
요소에 <CustomAttribute>
요소를 추가합니다.
<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>
추가 MotionLayout 속성
앞의 예시의 속성 외에도 MotionLayout
에는 지정할 수 있는 다른 속성이 있습니다.
app:applyMotionScene="boolean"
는 모션 장면을 적용할지 여부를 나타냅니다. 이 속성의 기본값은true
입니다.app:showPaths="boolean"
는 모션이 실행될 때 모션 경로를 표시할지 여부를 나타냅니다. 이 속성의 기본값은false
입니다.app:progress="float"
를 사용하면 전환 진행 상황을 명시적으로 지정할 수 있습니다.0
(전환 시작)부터1
(전환 종료)까지 부동 소수점 값을 사용할 수 있습니다.app:currentState="reference"
를 사용하면 특정ConstraintSet
를 지정할 수 있습니다.app:motionDebug
를 사용하면 모션에 관한 추가 디버그 정보를 표시할 수 있습니다. 가능한 값은"SHOW_PROGRESS"
,"SHOW_PATH"
또는"SHOW_ALL"
입니다.
추가 리소스
MotionLayout
에 관한 자세한 내용은 다음 리소스를 참고하세요.
- Kotlin 03.2의 고급 Android: MotionLayout을 사용한 애니메이션
- MotionLayout 예제
- GitHub의 MotionLayout/ConstraintLayout 샘플
- MotionLayout 소개(파트 I)
- MotionLayout 소개(파트 II)
- MotionLayout 소개(파트 III)
- MotionLayout 소개(파트 IV)