Manage motion and widget animation with MotionLayout

CmplxN·2021년 1월 21일

Android Developers

MotionLayout의 기본 문서를 읽어보자.

Introduction

MotionLayout은 ConstraintLayout의 subclass로 API 14까지 호환가능하다.
MotionLayout은 property animation framework, TransitionManager, CoordinatorLayout의 혼합체로 이해할 수 있다.
즉, layout 전환 및 속성 변화를 애니메이션으로 나타낼 수 있다.
그리고, 사용자 입력에 따라 애니메이션 내의 특정 포인트를 즉시 표현할 수 있다.
MotionLayout은 Keyframe 지원으로 좀더 커스터마이징 된 전환을 사용할 수 있다.
MotionLayout은 declarative로 motion을 복잡도와 상관없이 모두 XML에 표현할 수 있다.
MotionLayout은 Nested Layout에는 사용할 수 없고, Activity 전환에는 쓰일 수 없다.

Design consideration

MotionLayout은 Ui 구성요소들을 움직이거나 리사이징하거나 애니메이션을 추가할 때 쓴다.
Motion은 단순히 특수 효과를 나타내기 위해 쓰지 않아야한다.
Motion은 유저가 Application 사용에 도움이 되는 방향으로 구성해야한다.
Motion 사용의 철학(?)에 대해서는 다음 Material Design 문서를 참고하자.

Getting started

  • ConstraintLayout 2.0.0 이상의 dependency를 추가한다. (작성시점 최신 2.0.4)
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
  • MotionLayout 만들기 : ConstraintLayout과 다르게 app:layoutDescription속성이 추가되었다.
<?xml version="1.0" encoding="utf-8"?>
<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/activity_main_scene"
    tools:showPaths="true">

    <View
        android:id="@+id/button"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:background="@color/teal_200"
        android:text="Button" />

</androidx.constraintlayout.motion.widget.MotionLayout>
  • MotionScene 만들기
    MotionLayout의 app:layoutDescription가 참조하는 xml파일을 만든다.
    이곳에서 Motion과 관련된 description을 작성하게된다.
    참고로 MotionLayout마다 별도의 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:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start"
        motion:duration="1000">
        <OnSwipe
            motion:dragDirection="dragRight"
            motion:touchAnchorId="@+id/button"
            motion:touchAnchorSide="right" />
    </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:constraintSetXXX : ConstraintSet에 있는 시작과 끝점
      • motion:duration : motion의 duration을 milliseconds로 나타냄
    • OnSwipe (아직 정확힌..)
      • motion:touchAnchorId : swipe & drag 할 수 있는 뷰
      • motion:touchAnchorSide : 뷰를 오른쪽에서 drag한다.(?)
      • motion:dragDirection : 진행률(progress)가 높아지는 방향(?)
    • ConstraintSet : endpoint에 대한 Constraint 정의
      • Constraint : ConstraintLayout과 같은 방법으로 크기, 위치 표현

Interpolated attributes

MotionScene의 ConstraintSet의 Constraint에서 위치, 크기 말고도 다음을 표현할 수 있다.

  • alpha
  • visibility
  • elevation
  • rotation, rotationX, rotationY
  • translationX, translationY, translationZ
  • scaleX, scaleY

Custom attributes

ConstraintCustomAttribute에서 단순 위치, 크기 이외의 속성을 정의할 수 있다.
예를 들면 아래와 같이 선언할 수 있다.

<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>
  • motion:attributeName는 View의 setter/getter 메소드명과 같은 패턴으로 맞춰줘야한다.
    여기서는 setBackgroundColor()와 맞춰진 것이다.
  • motion:customXXXValue는 setter / getter 타입에 맞게 설정해준다. ColorValue, IntegerValue, FloatValue, StringValue, Dimension, Boolean이 제공된다.

Additional MotionLayout attributes

MotionLayout(MotionScene아니다)에 다음 attributes를 걸 수 있다.

  • app:applyMotionScene="boolean" : MotionScene 적용을 on / off 할 수 있다.
  • app:showPaths="boolean" : motion path를 보여줄지 정할 수 있다. default false다.
  • app:progress="float" : 0f와 1f사이의 transiton progress를 정할 수 있다.
  • app:currentState="reference" : 특정 ConstraintSet을 지정할 수 있다.
  • app:motionDebug="enum" : 'NO_DEBUG', 'SHOW_PROGRESS', 'SHOW_PATH' 그리고 'SHOW_ALL' 추가 디버그 정보를 정할 수 있다.

Additional resources

MotionLayout을 공부할 때 쓸만한 블로그 포스트, codelab, examples.. 자료들이다.

공식문서를 그대로 적어만 놓았지, 잘 모르겠는 부분이 아직 많으므로 Additional resources나 다른 포스트들을 보면서 익혀나가야겠다.
코루틴부터 해야되는데

profile
Android Developer

0개의 댓글