MotionLayout
는 앱에서 모션 및 위젯 애니메이션을 관리하는 데 도움이 되는 레이아웃 유형입니다. MotionLayout
는 ConstraintLayout
의 서브클래스이며 풍부한 레이아웃 기능을 기반으로 합니다. MotionLayout
는 ConstraintLayout
라이브러리의 일부로 지원 라이브러리로 제공됩니다.
MotionLayout
은 레이아웃 전환과 복잡한 모션 처리 사이를 연결하며 속성 애니메이션 프레임워크, TransitionManager
, CoordinatorLayout
사이의 혼합된 기능을 제공합니다.
레이아웃 사이의 전환 외에도 MotionLayout
을 사용하여 레이아웃 속성을 애니메이션으로 보여줄 수 있습니다. 또한 기본적으로 검색 가능 전환을 지원합니다. 즉, 터치 입력과 같은 일부 조건에 따라 전환 내의 포인트를 즉시 표시할 수 있습니다. MotionLayout
에서는 키프레임도 지원하므로 사용자의 필요에 맞게 완전히 맞춤설정된 전환을 사용할 수 있습니다.
MotionLayout
은 완전히 선언 가능하므로, 복잡도에 상관없이 XML로 모든 전환을 설명할 수 있습니다.
설계 고려사항
MotionLayout
은 버튼 및 제목 표시줄과 같이 사용자가 상호작용하는 UI 요소의 이동, 크기 조절 및 애니메이션에 사용합니다. 앱에서 모션을 불필요한 특수 효과로 사용하지 마세요. 이를 통해 사용자가 앱의 작동 방식을 이해하도록 지원하세요. 모션으로 앱을 디자인하는 방법에 관한 자세한 내용은 머티리얼 디자인 섹션 모션 이해를 참고하세요.
시작하기
프로젝트에서 MotionLayout
사용을 시작하려면 다음 단계를 따르세요.
-
ConstraintLayout
종속 항목 추가: 프로젝트에서MotionLayout
을 사용하려면ConstraintLayout
2.0 종속 항목을 앱의build.gradle
파일에 추가합니다. AndroidX를 사용하는 경우 다음 종속 항목을 추가합니다.Groovy
dependencies { implementation "androidx.constraintlayout:constraintlayout:2.2.0-beta01" // To use constraintlayout in compose implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01" }
Kotlin
dependencies { implementation("androidx.constraintlayout:constraintlayout:2.2.0-beta01") // To use constraintlayout in compose implementation("androidx.constraintlayout:constraintlayout-compose:1.1.0-beta01") }
-
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
scaleX
,scaleY
맞춤 속성
<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와 같이 뷰의 색상이 모션의 일부로 변경되도록 하려면 어떻게 해야 할까요?
다음 코드 스니펫과 같이 <CustomAttribute>
요소를 각 ConstraintSet
요소에 추가합니다.
<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)