카테고리 없음

Android MotionLayout(모션 레이아웃) basic3 (feat.codelab)

hik14 2024. 1. 15. 03:29

<KeyAttribute>

 

동적 애니메이션을 만든다는 것은 애니메이션이 진행됨에 따라 View의 크기, 회전 또는 알파를 변경하는 것을 의미하는 경우가 많습니다. MotionLayout은 KeyAttribute를 사용하여 모든 View에서 많은 속성에 대한 애니메이션을 지원합니다.

 

  • android:visibility : 가시성
  • android:alpha : 투명도
  • android:elevation : 높이
  • android:rotation : 회전 (양수: 시계방향, 음수: 반시계 방향)
  • android:rotationX 
  • android:rotationY
  • android:scaleX 크기 ("2"- 2배, "1/2"-절반축소)
  • android:scaleY
  • android:translationX 위치 ( "100dp" -> 100dp 만큼 이동)
  • android:translationY
  • android:translationZ

풍부한 애니메이션에는 뷰의 색상이나 기타 속성 변경이 포함됩니다.

MotionLayout은 KeyAttribute를 사용하여 위에 나열된 표준 속성을 변경할 수 있지만, CustomAttribute를 사용하여 다른 속성을 지정할 수 있습니다.

 

<CustomAttribute>

 

CustomAttribute는 attributeName과 설정할 값 하나를 지정해야 합니다.

<KeyAttribute
       motion:framePosition="100"
       motion:motionTarget="@id/moon">
   <CustomAttribute
           motion:attributeName="colorFilter"
           motion:customColorValue="#FFFFFF"
   />
</KeyAttribute>

 

Motion:attributeName은 이 CustomAttribute에 의해 호출될 setter의 이름입니다.

이 예에서는 Drawable의 colorFilter --> setColorFilter가 호출됩니다.

 

MotionLayout을 CoordinatorLayout과 함께 사용하면 풍부한 애니메이션을 구축할 수 있습니다. 

MotionLayout을 사용하여 축소 가능한 Appbar 알아보기.

 

1. 기본적인 CoordinatorLayout을 사용하는 포멧에 AppBarLayout 하위로 MotionLayout을 생성하고 Scene으로 애니메이션을 설정한다.

<androidx.coordinatorlayout.widget.CoordinatorLayout
       ...>
   <com.google.android.material.appbar.AppBarLayout
           android:id="@+id/appbar_layout"
           android:layout_width="match_parent"
           android:layout_height="180dp">
       <androidx.constraintlayout.motion.widget.MotionLayout
               android:id="@+id/motion_layout"
               ... >
           ...
       </androidx.constraintlayout.motion.widget.MotionLayout>
   </com.google.android.material.appbar.AppBarLayout>
  
   <androidx.core.widget.NestedScrollView
           ...
           app:layout_behavior="@string/appbar_scrolling_view_behavior" >
           ...
   </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

 

2. 최소로 줄어들 높이와 스크롤을 CoordinatorLayout이 감지 했을때 어떻게 할지 정한다.

android:minHeight="80dp"
app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed"

        <androidx.constraintlayout.motion.widget.MotionLayout
            android:id="@+id/motion_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:minHeight="80dp"
            app:layoutDescription="@xml/step8"
            app:motionDebug="SHOW_PATH"
            app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed">

 

3.  AppBarLayout.OnOffsetChangedListener에 OffSet에 따라 애니메이션 진행률을 설정한다.

 

 - 얼마나 줄었는가 / appBarLayout에서 전체 스크롤 되는 범위

 - verticalOffset / appBarLayout.totalScrollRange.toFloat()

private fun coordinateMotion() {
    val appBarLayout: AppBarLayout = findViewById(R.id.appbar_layout)
    val motionLayout: MotionLayout = findViewById(R.id.motion_layout)

    val listener = AppBarLayout.OnOffsetChangedListener { unused, verticalOffset ->
        val seekPosition = -verticalOffset / appBarLayout.totalScrollRange.toFloat()
        motionLayout.progress = seekPosition
    }

    appBarLayout.addOnOffsetChangedListener(listener)
}

 

AppBarLayout은 MotionLayout의 크기를 조정하지 않습니다.


AppBarLayout이 축소되면 MotionLayout View가 부분적으로 화면 밖으로 이동됩니다. 크기가 조정되지 않고 위로 이동되었습니다. MotionLayout 상단에 제약 조건이 있는 경우 애니메이션이 끝날 때 화면 밖으로 표시됩니다. AppBarLayout을 사용하려면 끝 제약 조건이 상위 항목의 아래쪽에 고정되어 있는지 확인하세요.