Android MotionLayout(모션 레이아웃) basic3 (feat.codelab)
<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을 사용하려면 끝 제약 조건이 상위 항목의 아래쪽에 고정되어 있는지 확인하세요.