Motion Layout EP.1
: Transition & CustomAttribute
MotionLayout เป็น subclass ของ ConstraintLayout ที่จะมาทำให้ layout ของเราเคลื่อนไหวได้ ความสามารถของ Motion layout เช่น การเคลื่อนย้าย(location) เปลี่ยนสี(color) ปรับขนาด(size) การหมุน(rotation) และอื่นๆอีกมากมาย
และที่ MotionLayout มีความสามารถหลากหลาย เนื่องจากเป็นส่วนผสมของคุณสมบัติระหว่าง property animation framework, TransitionManager และ CoordinatorLayout ค่ะ และยังรองรับ keyframes ด้วย ทำให้สามารถ customized transitions ได้อย่างเต็มที่ตามความต้องการเลยค่ะ
ข้อจำกัด
MotionLayout จะทำงานกับตัวลูกโดยตรงเท่านั้น ไม่รองรับ nested layout
Implementation
implementation ‘androidx.constraintlayout:constraintlayout:2.1.3’
MotionScene
ทำหน้าที่ customized transitions ต่างๆ ประกอบด้วย Transition ConstraintSet และ StateSet
- <Transition ทำหน้าที่กำหนดการเคลื่อนที่
motion:constraintSetStart อ้างอิง view เริ่มต้น
motion:constraintSetEnd อ้างอิงview สิ้นสุด
motion:duration ระยะเวลาในการเคลื่อนที่ตั้งแต่ start ถึง end
(1000 = 1000 milliseconds = 1 second) - <ConstraintSet เป็นกลุ่มของ view มี 2 ส่วนได้แก่ start และ end
ใน <ConstraintSet ประกอบด้วยหลายๆ <Contraint
<Transition
- <KeyFrameSet เพิ่มลูกเล่นระหว่าง transition เช่น ปรับ path ให้โค้ง หรือทำให้ view หมุนที่ position นั้นๆ
- <OnClick คลิ๊กเพื่อให้เกิด transition
- <OnSwipe ลากเพื่อให้เกิด transition
<OnClick
<OnClick
motion:clickAction="toggle"
motion:targetId="@+id/bgBottomImageView" />
- motion:clickAction ระบุ action จะต้องการเมื่อคลิ๊ก ตัวอย่างเช่น
- transitionToEnd เคลื่อนไปยังตำแหน่ง end
- toggle เคลื่อนสลับไปมา start -> end -> start -> end -> … - motion:targetId อ้างอิง id ที่จะคลิ๊ก
<OnSwipe
<OnSwipe
motion:dragDirection="dragUp"
motion:touchAnchorId="@id/bgBottomImageView"
motion:touchAnchorSide="top" />
- motion:dragDirection ทิศทางการลาก เช่น dragUp(ลากขึ้น) dragRight(ลากไปทางขวา)
- motion:touchAnchorId อ้างอิง id ต้องการ touch
- motion:touchAnchorSide บอกว่า เราจะ touch ไปทางไหน ควรสอดคล้องกับ dragDirection
<KeyFrameSet
อ่านได้ที่นี่ >> MotionLayout : KeyFrame
<CustomAttribute
- change image (ImageFilterView)
start : QR code image
end : plane image
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/imageFilterView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_qr_code"
app:altSrc="@drawable/ic_plane_rotation"
app:layout_constraintBottom_toBottomOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toTopOf="@id/imageView"
app:overlay="false" />--------------------------------------------------------------------<MotionScene ...
<Transition ... />
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/imageFilterView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
... >
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="0" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/imageFilterView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
... >
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="1" />
</Constraint>
</ConstraintSet>
</MotionScene>
2. change circle bg color (ShapeableImageView)
start : blue color
end : peach color
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/bgCircleImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/blue"
...
app:shapeAppearanceOverlay="@style/ShapeAppearance.Circle" />--------------------------------------------------------------------<MotionScene ...
<Transition ... />
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/bgCircleImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
... >
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="@color/blue" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/bgCircleImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
... >
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="@color/peach" />
</Constraint>
</ConstraintSet>
</MotionScene>
3. change text color
start : white color
end : black color
<com.google.android.material.textview.MaterialTextView
android:id="@+id/startDestinationTextView"
style="@style/LargeTitle.White"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/short_bkk_airport"
... />
--------------------------------------------------------------------<MotionScene ...
<Transition ... />
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/startDestinationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
... >
<CustomAttribute
motion:attributeName="textColor"
motion:customColorValue="@color/white" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/startDestinationTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
... >
<CustomAttribute
motion:attributeName="textColor"
motion:customColorValue="@color/black" />
</Constraint>
</ConstraintSet>
</MotionScene>
4. change image color
start : white color
end : black color
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/planeImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android. :adjustViewBounds="true"
android:src="@drawable/ic_airplane"
... />
--------------------------------------------------------------------<MotionScene ...
<Transition ... />
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/planeImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
... >
<CustomAttribute
motion:attributeName="ColorFilter"
motion:customColorValue="@color/white" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/planeImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
... >
<CustomAttribute
motion:attributeName="ColorFilter"
motion:customColorValue="@color/black" />
</Constraint>
</ConstraintSet>
</MotionScene>
Source Code: https://github.com/lookmoojin/BoardingPass
ข้อมูลเพิ่มเติม
https://developer.android.com/training/constraint-layout/motionlayout#androidx
https://developer.android.com/training/constraint-layout/motionlayout/examples