รู้ยัง? Android เค้าทำ Animation ได้แล้วนะ!!!

Supakorn Komolhatai
te<h @TDG
Published in
4 min readMar 26, 2020
https://urbancreature.co/chao-khun-tong/

อรุณเบิกฟ้า…นกกาโบยบิน ออกหากินร่าเริงแจ่มใส เราเบิกบานรีบมาเร็วไว ยิ้มรับวันใหม่ยิ้มให้แก่กัน เจ้าขุนทองมาแล้ว ใครทันเพลงนี้บ้างครับ สิ่งที่ผมจะมานำโชว์ วันนี้ไม่เกี่ยวกับเพลงข้างต้นเท่าไหร่เลย อ้าว…แล้วผมจะเกริ่นทำไมกัน นั่นหนะสิ…นั่นหนะสิๆ…

หลายๆท่านคงจะชอบดูการ์ตูนในตอนเด็กใช่ไหม วันนี้เจ้าขุนทองจะมาโชว์ของดีให้ทุกท่านได้ชมกันครับ มาติดตามกันได้เล่ยยยยย

งาน Google I/O 2018 ได้มีการพูดถึง Constraint layout แบบใหม่ไว้แล้ว นั่นก็คือ MotionLayoutนั่นเอง โดยMotionLayout classจะอยู่ภายใต้ ConstraintLayout 2.0 library ให้เราได้สามารถเรียกใช้งานเพื่อจัดการMotion และwidgetต่างๆ

Constraint layout 2.0 สนับสนุนการทำงานตั้งแต่API level 14(ICS) หมายความว่า สามารถใช้งานกับอุปกรณ์androidได้99.8%บนโลกนี้ แต่ทั้งนี้ยังอยู่ในขั้นตอนการทดสอบbetaอยู่ และถ้าหากต้องการใช้MotionLayoutบนGraphic design tool จะต้องนำไปพัฒนาบนAndroid studio 4.0ขึ้นไป ซึ่งเป็นpreview releaseอยู่

MotionLayout คืออะไรกัน??? จิ๊บๆๆๆ ขุนทองงงมากเลยจ้าแม่

เป็นlayoutที่ผสมผสานกันระหว่างlayout transition และmotion handlingที่ซับซ้อน ซึ่งทำให้เราสามารถกำหนดactionต่างๆให้กับviewได้อย่างเต็มที่ ในระหว่างที่ view นั้นๆกำลังเคลื่อนไหวจาก frame หนึ่งไปยัง frame หนึ่ง หรือจะเรียกว่าการสร้าง view ที่เคลื่อนไหวได้นั่นเอง เอาหละ… เพื่อให้เห็นภาพ เรามาลองใช้กันเถอะ

หนูควรใช้งานตอนไหนเอ่ย???

ควรใช้งานเมื่อคุณต้องการเคลื่อนย้าย, เพิ่มลดขนาด และกำหนด animationให้กับ UI ไม่ว่าจะเป็น Button, Title Bar และอื่นๆอีกมากมาย เป็นต้น โดย UI เหล่านั้นผู้ใช้งานจะมีปฏิสัมพันธ์กับมัน ซึ่งผมจะขอขยายให้เห็นภาพตัวอย่างเบื้องต้นจากตัวอย่างด้านล่างดังต่อไปนี้ครับ

Example มาทำ slidebar อย่างง่าย เพื่อสร้าง animationให้รูปภาพกันเถอะ จิ๊บๆๆๆ

ทำการใส่ Constraint layout 2.0 ลงใน gradle file

dependencies {
implementation ‘com.android.support.constraint:constraint-layout:2.0.0-alpha4’
}

สร้าง view ของเราให้เรียบร้อยด้วย Constraint layout ตามอย่างที่เราคุ้นเคย ง่ายไปเลยใช่ม้าาางับ

<!--activity_main.xml--><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<View
android:id="@+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:background="@android:color/holo_red_dark"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginLeft="32dp"
android:layout_marginEnd="32dp"
android:layout_marginRight="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.18"
app:srcCompat="@drawable/logo_trueid_large" />

</androidx.constraintlayout.widget.ConstraintLayout>

คลิกที่ขวาที่ view แล้วเลือก Convert to MotionLayout ได้เล้ยยยยย

ไฟล์ activity_main.xml ของเราจะเปลี่ยนไปเป็นดังนี้ เจี๊ยกๆๆอ้าวว เราเป็นลิงหรือนกกันแน่อ้า หนูงง????

<!--activity_main.xml--><?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:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/activity_main_scene"
tools:context=".MainActivity">

<View
android:id="@+id/button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:background="@android:color/holo_red_dark"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginLeft="32dp"
android:layout_marginEnd="32dp"
android:layout_marginRight="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.18"
app:srcCompat="@drawable/logo_trueid_large" />

</androidx.constraintlayout.motion.widget.MotionLayout>

จะมีการสร้างไฟล์สำหรับเก็บ MotionScene เอาไว้ ซึ่งจะถูกกำหนดไว้ใน layoutDescription ซึ่งชื่อว่า activity_main_scene

app:layoutDescription="@xml/activity_main_scene"

โดยไฟล์ของ MotionScene จะประกอบไปด้วย element เริ่มต้น เช่น ConstrainSet ของ Start frame, End frame และTransitionระหว่างConstrainSet เป็นต้น โหว…น่าสนใจจ้าาาา

<!--activity_main_scene.xml--><?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">
<KeyFrameSet>
</KeyFrameSet>
</Transition>

<ConstraintSet android:id="@+id/start">
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
</ConstraintSet>
</MotionScene>

ซึ่งสามารถมองเห็นภาพอย่างง่ายได้จากMotion editor ในแถบ Design ของ xml

ให้เราคลิกที่ ConstraintSet end แล้วจัดวางตำแหน่ง layout เฟรมสุดท้ายที่ต้องการให้เคลื่อนไหว โดยในที่นี้จะเลื่อนไปทางขวาสุด จะได้ดังนี้

เมื่อจัดวางเสร็จแล้ว ให้เรากดที่ลูกศรtransitionที่อยู่ด้านบน จะทำให้motionต่างๆถูกset

แต่ยังขาดอีกหนึ่งอย่าง คือ การเพิ่มSwipe handlerให้กับกล่องslidebarสี่เหลี่ยม เพื่อทำให้เราสามารslideกล่องได้ และ transition จะถูก trig ให้ทำงาน เราต้องทำการคลิกสร้างจากปุ่มด้านบนดังนี้

ทำการใส่ setting ต่างๆให้เรียบร้อย แล้วกด Add

touchAnchorId คือ idของviewที่จะนำมาใช้ในการinteractive เพื่อให้transition ทำงาน

touchAnchorSide คือ ลักษณะท่าทางการtouch ที่จะทำให้viewเกิดการเคลื่อนที่ เช่น top, left, right, bottom เป็นต้น

dragDirection คือ ทิศทางที่จะกำหนดให้viewเคลื่อนที่ เช่น dragUp, dragDown, dragLeft, dragRight เป็นต้น

แจ่มจะแดมแจ่ม Wow ณ บัด Now นั้นโดนใจ ผลลัพธ์ที่ได้จะเป็นดังนี้นั่นเองง

เราสามารถเพิ่มความน่าสนใจระหว่างกล่องbutton และimageViewได้อีก โดยการระบุค่า alpha = 0, 1 ให้กับ keyframe ของ constraint start และ constraint end เพื่อให้imageViewมีการแสดงผลความสว่างตามการเลื่อนของbutton

ให้ทำการคลิกที่ลูกศร transition ระหว่าง constraint ด้านบน เพื่อให้หน้าต่างจัดการframeปรากฏขึ้น แล้วเลื่อนตำแหน่งframeด้านล่างไปที่ 0 จากนั้นคลิกเพิ่มkeyAttributeจากปุ่มCreate KeyFrames

เลือกKeyAttribute

จากนั้นทำการตั้งค่า KeyAttribute ต่างๆ แล้วทำการกด Add

ID คือ idของviewที่จะถูกกระทำจากattributeนี้

Position คือตำแหน่งของkeyframeที่จะเกิดactionนี้ ขึ้นกับview

Attribute คือ ประเภทของactionต่างๆที่จะเกิดขึ้นกับviewนี้ เช่น alpha, rotation, scaleX และscaleY เป็นต้น

ดับเบิ้ลคลิกที่จุด keyframe 0 แล้วทำการตั้งค่า alpha เป็น 0

ให้เราเลื่อน keyframe ไปที่ตำแหน่ง 100 แล้วสร้าง keyAttribute เช่นเดียวกัน เพื่อทำการ set ค่า alpha เท่ากับ 1 ที่ frame สุดท้าย

ท่าด่ามมมมมมมมม ผลลัพธ์จะออกมาเป็นดังนี้จ้าาาาาาาา

ตอนนี้เราจะได้ animation ที่สวยงามไว้ใช้งานกันแล้ววว ขุนทองต้องลาไปก่อนน้าาา บุยบุยๆๆๆๆๆ จิ๊บๆๆๆๆ

ตัวอย่างworkshopครับ

สามารถอ่านเพิ่มเติมได้ที่ลิ้งด้านล่างนะจ๊ะ

--

--