MotionLayout 은 앱에서 모션과 위젯 애니메이션을 관리하는 데 사용할 수 있는 레이아웃 유형입니다.

MotionLayout 은 ConstraintLayout 의 서브클래스이며 ConstraintLayout 의 다양한 레이아웃 기능을 기초로합니다.

ConstraintLayout 라이브러리의 일부인 MotionLayout 은 지원 라이브러리로 사용 가능하며, API 레벨 14와 호환됩니다.

그림 1. 기본터치 컨트롤 모션입니다.

 

MotionLayout 은 레이아웃 전환과 복잡한 모션 처리를 연결하며 속성 애니메이션 프레임워크, TransitionManager 및 CoordinatorLayout 의 혼합된 기능을 제공합니다. 

 

레이아웃 사이의 전환 외에도 MotionLayout 을 통해 레이아웃 속성에 애니메이션을 적용할 수 있습니다.

한  기본적으로 검색 가능 전환(seekable transitions)을 지원합니다. 이 말은 터치 입력과 같은 어떤 조건을 기준으로 전환 내의 어떤 포인트를 즉시 보여줄 수 있다는 것을 의미합니다. 또한 MotionLayout에서는 키프레임도 지원하므로 사용자의 필요에 맞게 완전히 맞춤설정된 전환을 사용할 수 있습니다.

 

MotionLayout 은 완전히 선언적인 것으로, 복잡도에 상관없이 XML로 모든 전환을 설명할 수 있습니다.

 ☆참고 : MotionLayout은 직접 하위 요소와만 호환됩니다. 중첩 레이아웃 계층 구조 또는 액티비티 전환은 지원하지 않습니다. 

디자인 고려 사항 

MotionLayout 은 버튼 및 제목 표시줄과 같이 사용자가 상호작용하는 UI 요소를 이동, 크기 조절 및 애니메이션화하기 위한 것입니다. 앱의 모션은 단지 애플리케이션의 불필요한 특수 효과가 되어서는 안 됩니다. 사용자가 애플리케이션 기능을 이해하는 데 도움이 되어야 합니다. 모션을 사용하여 앱을 디자인하는데 관한 자세한 내용은 모션 이해의 머티리얼 디자인 섹션을 참조하세요. 

 시작하기

 프로젝트에서 MotionLayout 사용을 시작하려면 다음 단계를 따르세요.

1. ConstraintLayout 종속 항목 추가

프로젝트에서 MotionLayout 을 사용하려면 ConstraintLayout 2.0 종속 항목을 앱의 build.gradle 파일에 추가합니다.

AndroidX를 사용중이라면 다음 종속 항목을 추가하세요. 

    dependencies {
        implementation
'androidx.constraintlayout:constraintlayout:2.0.0-beta1'
   
}   

 AndroidX를 사용하지 않으면 다음 지원 라이브러리 종속성을 추가하세요.

    dependencies {
        implementation
'com.android.support.constraint:constraint-layout:2.0.0-beta1'
   
}

2. MotionLayout 파일 만들기

MotionLayout은  ConstraintLayout 의 서브클래스이므로 다음 예에서와 같이 레이아웃 리소스 파일에서 클래스 이름을 바꿔 기존 ConstraintLayout을 MotionLayout 으로 전환할 수 있습니다.

    <!-- before: ConstraintLayout -->
   
<androidx.constraintlayout.widget.ConstraintLayout .../>
   
<!-- after: MotionLayout -->
   
<androidx.constraintlayout.motion.widget.MotionLayout .../> 

다음은 그림 1에서 모션을 생성하는 데 사용할 수 있는 MotionLayout 파일의 전체 예입니다.

    <?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>
            

3. MotionScene 만들기

이전 MotionLayout 예에서 app:layoutDescription 속성은 MotionScene 을 참조합니다.

MotionScene 은 해당 레이아웃의 모든 모션 설명을 포함하는 XML 리소스 파일입니다.

레이아웃 정보를 모션 설명과 별도로 유지하기 위해 각 MotionLayout 은 별도의 MotionScene을 참조합니다.

MotionScene의 정의는 MotionLayout 의 유사한 정의보다 우선한다는 점에 유의합니다.

    <?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 는 모션의 엔드포인트 참조입니다. 
이러한 엔드포인트는 나중에 <MotionScene>의 <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" 사용). 가로로는 화면의 맨 왼쪽과 오른쪽에 엔드포인트가 있습니다.

 Interpolated Attributes

 MotionScene 파일에서 COnstraintSet 요소에는 전환하는 동안 추가되는 추가 속성이 포함될 수 있습니다. 위치 및 경계 이외에 다음 속성은 MotionLayout을 통해 추가됩니다.

  • alpha

  • visibility

  • rotation, rotationX, rotationY

  • translationZ, translationY, translationX

  • scaleX, scaleY

Custom attributes

<Constraint> 에서 <CustomAttribute> 요소를 사용하여 위치 또는 View 속성과 관련되지 않은 속성의 전환을 지정할 수 있습니다. 

    <Constraint
        android:id="@+id/button" ...>
        <CustomAttribute
            motion:attributeName="backgroundColor"
            motion:customColorValue="#D81B60"/>
    </Constraint>

<CustomAttribute> 에는 다음과 같은 두 가지 고유 속성이 있습니다.

  • motion:attributeName 은 필수이며 getter 및 setter 메서드가 있는 객체와 일치해야 합니다.
    getter와 setter는 특정 패턴과 일치해야 합니다. 예를 들어, Google의 View에는 기본적으로 getBackgroundColor() 및 setBackgroundColor() 메서드가 있으므로 backgroundColor 가 지원됩니다.

  • 입력해야하는 다른 속성은 값 유형을 기반으로 합니다. 지원되는 다음 유형 중에서 선택하세요.

    • motion:customColorValue - 색상
    • motion:customIntegerValue - 정수
    • motion:customFloatValue - 부동수
    • motion:custromStringValue - 문자열
    • motion:customDimension - 측정기준
    • motion:customBoolean - 부울

 맞춤 속성을 지정할 때 시작 및 종료 <ConstraintSet> 요소 모두에 엔드포인트 값을 정의해야합니다.

 예: 배경색 변경

 앞의 예를 기반으로 그림 2에 표시된 대로 보기에서 모션의 일부로 색상을 변경해 보겠습니다.

그림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" 은 MotionScene 적용 여부를 나타냅니다.
    이 속성의 기본값은 true 입니다.

  • app:showPaths="boolean" 은 모션이 실행 중일 때 모션 경로를 표시할지 나타냅니다.
    이 속성의 기본값은 false 입니다.

  • app:progress="float" 를 사용하면 전환 진행 상황을 명시적으로 지정할 수 있습니다.
    0(전환시작)부터 1(전환종료)까지 부동 소수점 값을 사용할 수 있습니다.

  • app:currentState="reference" 를 사용하면 특정 ConstraintSet 를 지정할 수 있습니다.
  • app:motionDebug 를 사용하면 모션에 관한 추가 디버그 정보를 표시할 수 있습니다.
    가능한 값은 'SHOW_PROGRESS', 'SHOW_PATH' 또는 'SHOW_ALL' 입니다.

SUMMARY

MotionLayout 은 앱에서 모션과 위젯 애니메이션을 관리하는 데 사용할 수 있는 레이아웃 유형입니다.

기본적으로 검색 가능 전환(seekable transitions)을 지원합니다. 이 말은 터치 입력과 같은 어떤 조건을 기준으로 전환 내의 어떤 포인트를 즉시 보여줄 수 있다는 것을 의미합니다. 또한 키프레임도 지원하므로 사용자의 필요에 맞게 전환을 사용할 수 있습니다.

 

MotionScene은 해당 레이아웃의 모든 모션 설명을 포함하는 XML 리소스이며, 레이아웃 정보를 모션 설명과 별도로 유지하기 위해 MotionLayout은 별도의 MotionScene을 참조합니다. MotionScene의 정의는 MotionLayout 의 유사한 정의보다 우선합니다.

 

<Transition> 에는 모션의 기본 정의가 포함되어 있습니다.

motion:constraintSetStart 및 motion:constraintSetEnd 는 모션의 엔드포인트 참조입니다. 
이러한 엔드포인트는 나중에 <MotionScene>의 <ConstraintSet> 요소에 정의됩니다.

 

<OnSwipe> 를 사용하면 터치를 통해 모션을 제어할 수 있습니다.

<ConstraintSet> 를 통해서는 모션을 설명하는 다양한 제약조건을 정의합니다.

 

<CustomAttribute> 에는 다음과 같은 두 가지 고유 속성이 있습니다.

  • motion:attributeName 은 필수이며 getter 및 setter 메서드가 있는 객체와 일치해야 합니다.
    getter와 setter는 특정 패턴과 일치해야 합니다. 

  • 입력해야하는 다른 속성은 값 유형을 기반으로 합니다. 

맞춤 속성을 지정할 때 시작 및 종료 <ConstraintSet> 요소 모두에 엔드포인트 값을 정의해야합니다.

Reference

MotionLayout : developer.android.com/training/constraint-layout/motionlayout?hl=ko#androidx

'Android > Android Developer' 카테고리의 다른 글

Layout 레이아웃  (0) 2020.12.01
ConstraintLaytout  (0) 2020.11.02

+ Recent posts