Motion Layout EP.1

Natcha Jintanasatien
te<h @TDG
Published in
3 min readJun 2, 2022

: Transition & CustomAttribute

MotionLayout เป็น subclass ของ ConstraintLayout ที่จะมาทำให้ layout ของเราเคลื่อนไหวได้ ความสามารถของ Motion layout เช่น การเคลื่อนย้าย(location) เปลี่ยนสี(color) ปรับขนาด(size) การหมุน(rotation) และอื่นๆอีกมากมาย

และที่ MotionLayout มีความสามารถหลากหลาย เนื่องจากเป็นส่วนผสมของคุณสมบัติระหว่าง property animation framework, TransitionManager และ CoordinatorLayout ค่ะ และยังรองรับ keyframes ด้วย ทำให้สามารถ customized transitions ได้อย่างเต็มที่ตามความต้องการเลยค่ะ

อ้างอิงจาก https://medium.com/google-developers/introduction-to-motionlayout-part-i-29208674b10d

ข้อจำกัด

MotionLayout จะทำงานกับตัวลูกโดยตรงเท่านั้น ไม่รองรับ nested layout

Implementation

implementation ‘androidx.constraintlayout:constraintlayout:2.1.3’

MotionScene

ทำหน้าที่ customized transitions ต่างๆ ประกอบด้วย Transition ConstraintSet และ StateSet

ตัวอย่าง MotionScene ตั้งต้น
  1. <Transition ทำหน้าที่กำหนดการเคลื่อนที่
    motion:constraintSetStart อ้างอิง view เริ่มต้น
    motion:constraintSetEnd อ้างอิงview สิ้นสุด
    motion:duration ระยะเวลาในการเคลื่อนที่ตั้งแต่ start ถึง end
    (1000 = 1000 milliseconds = 1 second)
  2. <ConstraintSet เป็นกลุ่มของ view มี 2 ส่วนได้แก่ start และ end
    ใน <ConstraintSet ประกอบด้วยหลายๆ <Contraint

<Transition

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

ตัวอย่าง CustomAttribute
  1. 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

https://developer.android.com/studio/write/motion-editor

--

--