Manage motion and widget animation with MotionLayout

CmplxN·2021년 1월 21일
0

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개의 댓글