การทำอนิเมชั่นโดยใช้ ConstraintLayout ในแอนดรอยด์ (Android)
สวัสดีครับ วันนี้จะเป็นบทความแรกของแอนดรอยด์ (Android) ที่เขียนเป็น Kotlin ซึ่งจริงๆ ก็ยังไม่รู้เรื่องกับเจ้าภาษานี้มากเท่าไหร่นัก. วันนี้จะเป็นการทำอนิเมชั่น (Animation) ของ ConstrainLayout เลเอาท์แบบใหม่ของแอนดรอยด์ ซึ่งถ้าสงสัยว่าอนิเมชั่นนี้เป็นอย่างไรก็สามารถดูได้ตามคลิปวิดีโอด้านล่างได้เลยครับ ผมว่ามันมีความเจ๋งอยู่ในการทำอนิเมชั่นแบบนี้ จึงได้นำมาซึ่งบทความในวันนี้นั้นเอง
ก่อนที่เราจะไปเข้าโค้ด เรามีดูในส่วนประกอบไฟล์อื่นๆก่อน ในตัวอย่างนี้จะมีการใช้ไฟล์ gradient.xml และ gradient_variant.xml ในโฟลเดอร์ drawable ซึ่ง 2 ไฟล์นี้ก็คือการทำภาพเลเอาท์ให้มันเบลอๆนั้นเอง หน้า xml 2 หน้าที่เบลอก็เพราะ 2 ไฟล์นี้นั้นแหละครับ
gradient.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <gradient android:angle="90" android:endColor="#00181818" android:centerColor="#99181818" android:startColor="#181818"/> <corners android:radius="0dp" /> </shape>
gradient_variant.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" > <gradient android:angle="90" android:endColor="#00181818" android:centerColor="#d9181818" android:startColor="#181818"/> <corners android:radius="0dp" /> </shape>
circuit.xml
circuit.xml |
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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:id="@+id/constraint" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#181818" tools:context=".MainActivity"> <ImageView android:id="@+id/backgroundImage" android:layout_width="0dp" android:layout_height="0dp" android:scaleType="centerCrop" android:src="@drawable/sea" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#d3d3d3" android:paddingBottom="3dp" android:paddingEnd="16dp" android:paddingStart="16dp" android:paddingTop="3dp" android:text="JUNE 3, 2018" android:textSize="12sp" app:layout_constraintBottom_toBottomOf="@+id/title" app:layout_constraintRight_toRightOf="@+id/title" /> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:background="#F44336" android:paddingBottom="8dp" android:paddingEnd="24dp" android:paddingStart="24dp" android:paddingTop="8dp" android:text="Maldives" android:textColor="#FFFF" android:textSize="45sp" app:layout_constraintRight_toLeftOf="@+id/backgroundImage" app:layout_constraintTop_toTopOf="parent" /> <View android:id="@+id/fadeBackgroudView" android:layout_width="wrap_content" android:layout_height="90dp" android:foreground="@drawable/gradient_variant" app:layout_constraintBottom_toTopOf="@+id/description" /> <TextView android:id="@+id/tap" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="12dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:text="Tap for info" android:textColor="#ffffff" android:textSize="15sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <TextView android:id="@+id/description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#181818" android:gravity="center" android:paddingBottom="8dp" android:paddingEnd="8dp" android:paddingStart="8dp" android:text="The Maldives was a Commonwealth republic from July 1982 until its withdrawal from the Commonwealth in October 2016 in protest of international criticism of its records in relation to corruption and human rights." android:textColor="#FFFF" android:textSize="22sp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/backgroundImage" /> </android.support.constraint.ConstraintLayout>
circuit_detail.xml
circuit_detail.xml |
หน้า circuit_detail.xml หน้าแสดงข้อมูลต่างๆของไฟล์ หน้านี้เรามาสามารถตกแต่งหน้าตาให้สละสรวยได้อย่างตามใจชอบเลย โดยข้อมูลต่างๆ อยู่ภายใต้ ConstraintLayout ซึ่งข้อมูลนั้นก็จะเหมือนกันไฟล์ circuit.xml เลย
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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"> <ImageView android:id="@+id/backgroundImage" android:layout_width="0dp" android:layout_height="0dp" android:scaleType="centerCrop" app:layout_constraintBottom_toTopOf="@+id/description" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="48dp" android:background="#F44336" android:paddingBottom="8dp" android:paddingEnd="24dp" android:paddingStart="24dp" android:paddingTop="8dp" android:text="Maldives" android:textColor="#FFFF" android:textSize="45sp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Mar 9, 2018" app:layout_constraintRight_toRightOf="@+id/title" app:layout_constraintTop_toBottomOf="@+id/title" android:textSize="12sp" android:background="#d3d3d3" android:paddingStart="16dp" android:paddingEnd="16dp" android:paddingTop="3dp" android:paddingBottom="3dp"/> <View android:id="@+id/fadeBackgroudView" android:layout_width="wrap_content" android:layout_height="30dp" android:foreground="@drawable/gradient" app:layout_constraintBottom_toTopOf="@+id/description" /> <TextView android:id="@+id/tap" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:text="Tap for info" android:textSize="15sp" android:textColor="#ffffff" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <TextView android:id="@+id/description" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="The Maldives was a Commonwealth republic from July 1982 until its withdrawal from the Commonwealth in October 2016 in protest of international criticism of its records in relation to corruption and human rights." android:textSize="22sp" android:textColor="#FFFF" android:gravity="center" android:background="#181818" android:paddingStart="8dp" android:paddingEnd="8dp" android:paddingBottom="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> </android.support.constraint.ConstraintLayout>
MainActivity.kt
ไฟล์ MainActivity.kt เมื่อเราใช้ kotlin นามสกุลไฟล์ก็จะกลายเป็น .kt ถ้าสังเกตดีๆโค้ดนั้นจะสั้นลงกว่าการใช้ java เขียนมากถึงมากๆ โดยที่เราไปดูตาม method กันนะครับ ในไฟล์นี้จะมีหลัก hideComponents() กับ showComponents() 2 method หลักๆ แปปลตรงตัวก็คือ ซ่อน กับ แสดงนั้นแหละ
เพียงแต่ว่า hideComponents() จะแสดง circuit_detail.com แต่ว่า showComponents() จะแสดง circuit.xml แค่นั้นเอง และก็ใส่อนิเมชั่นเข้าไปในการเลื่อนไปแสดงตาม Layout
import android.annotation.TargetApi import android.os.Build import android.os.Bundle import android.support.annotation.RequiresApi import android.support.constraint.ConstraintSet import android.support.v7.app.AppCompatActivity import android.transition.ChangeBounds import android.transition.TransitionManager import android.view.animation.AnticipateOvershootInterpolator import kotlinx.android.synthetic.main.circuit.* class MainActivity : AppCompatActivity() { private var show = false @RequiresApi(Build.VERSION_CODES.KITKAT) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.circuit) backgroundImage.setOnClickListener { if(show) hideComponents() // if the animation is shown, we hide back the views else showComponents() // if the animation is NOT shown, we animate the views } } @TargetApi(Build.VERSION_CODES.KITKAT) private fun showComponents(){ show = true val constraintSet = ConstraintSet() constraintSet.clone(this, R.layout.circuit_detail) val transition = ChangeBounds() transition.interpolator = AnticipateOvershootInterpolator(1.0f) transition.duration = 1200 TransitionManager.beginDelayedTransition(constraint, transition) constraintSet.applyTo(constraint) } @RequiresApi(Build.VERSION_CODES.KITKAT) private fun hideComponents(){ show = false val constraintSet = ConstraintSet() constraintSet.clone(this, R.layout.circuit) val transition = ChangeBounds() transition.interpolator = AnticipateOvershootInterpolator(1.0f) transition.duration = 1200 TransitionManager.beginDelayedTransition(constraint, transition) constraintSet.applyTo(constraint) } }
สำหรับตัวอย่างนี้ก็เป็นตัวอย่างการทำอนิเมชั่นง่ายๆ นะครับ สามารถนำไปกระยุกต์ได้เยอะแยะมากมาย และก็มีข้อมูลไม่เยอะด้วยหวังว่าจะสามารถทำได้ทุกคนนะครับบบบบบบบ
ตัวอย่างซอสโค้ด
Credit by : https://android.jlelse.eu/build-awesome-animations-with-7-lines-of-code-using-constraintlayout-854e8fd3ad93
ความคิดเห็น