Android Kotlin

Membuat Animasi Android Dengan Layout FlexBox

June 16, 2019

Artikel ini di buat terinspirasi dari pertanyaan di forum facebook, nah kasusnya adalah membuat animasi seperti aplikasi duolingo seperti ini.

Kira — kira animasinya seperti video diatas, terlihatnya seperti rumit ya animasinya. Sebenarnya konsepnya cukup simple, yaitu memindahkan view secara diagonal berdasarkan posisi x da y. Namun sebelum itu kita perlu membahas beberapa hal terlebih dahulu.

FlexBox Layout

Yang perlu di perhatikan pada saat kita berurusan dengan animasi maka kita perlu bermain didalam satu viewgroup saja. Sedangkan pada kasus ini yang cukup ribet adalah urusan layoutnya saja.

FlexboxLayout ini adalah salah satu opensource viewgroup dari google yang kita bisa gunakan secara gratis.

implementation 'com.google.android:flexbox:1.0.0'

Dan berikut ini adalah layout yang akan kita buat :

Ilustrasi Animasi

Jika kita lihat diatas kita bisa saja membuat view diatas dengan ConstraintLayout. Akan tetapi jadi masalah jika berurusan dengan data yang dinamis. Maka disini kita perlu menggunakan viewgroup yang bisa mengatur posis dari childview nya secara dinamis.

<com.google.android.flexbox.FlexboxLayout
    android:id="@+id/answerBox"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="20dp"
    app:flexDirection="row_reverse"
    app:flexWrap="wrap"
    app:justifyContent="center"
    app:layout_constraintTop_toBottomOf="@+id/question">

    <View
        android:id="@+id/lineFirst"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="50dp"
        android:background="#b1b1b1" />

    <View
        android:id="@+id/lineSecond"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="50dp"
        android:background="#b1b1b1"/>

</com.google.android.flexbox.FlexboxLayout>

Dari view diatas kita menggunakan app:flexDirection=”row” yang ini berguna untuk membuat direksi childviewnya selalu bertambah kesamping. Dan untuk app:flexWrap=”wrap” akan membuat child view otomatis bertambah kebawah. Dan untuk membuat semua view berada di tengah kita menggunakan app:justifyContent=”center”.

Selanjutnya kita bisa mengenerate view secara dinamis pada FlexboxLayout seperti ini :

val answerOption = listOf(
        "morning",
        "are",
        "where",
        "not",
        "have",
        "How",
        "you"
)

answerOption.forEach {
    val key = TextView(answerBox.context)
    with(key){
        answerBox.addView(this)
        setBackgroundColor(Color.WHITE)
        text = it
        textSize = 18F
        setPadding(40, 20, 40, 20)
        val margin = key.layoutParams as FlexboxLayout.LayoutParams
        margin.setMargins(30, 30, 30, 30)
        layoutParams = margin
        setOnClickListener {
            moveToAnswer(it)
        }
    }
}

Animation

Untuk animasinya cukup simple saja kita hanya perlu memindahkan view secara diagonal berdasarkan sumbu x dan y.

view.animate()
        .setListener(completeMove)
        .x(leftPosition)
        .y(topPosition)

Untuk mendapatkan posisi x dan y seperti ini :

val topPosition = lineFirst.y - 120F

var leftPosition = lineFirst.x
if (listAnswers.size > 1) {
    var allWidth = 0F
    listAnswers.forEach {
        allWidth += (it.view?.width)?.toFloat()!! + 20F
    }
    allWidth -= (view.width).toFloat()
    leftPosition = lineFirst.x + allWidth
}

Jadi yang dilakukan pada kode diatas menghitung posisi view yang telah dipindahkan keatas dan ditambahkan jarak antara view nya 20F.

allWidth += (it.view?.width)?.toFloat()!! + 20F

Selanjutnya kita juga perlu menyimpan state view jadi kita bisa mengembalikan view pada posisi semula jika user salah pilih.

data class Answer(
        var view: View? = null,
        var actualPositionX: Float = 0F,
        var actualPositionY: Float = 0F,
        var text: String = "",
        var removeListener: RemoveAnswerListener? = null
){
    init {
        view?.setOnClickListener {
            it.animate()
                .x(actualPositionX)
                .y(actualPositionY)
            removeListener?.onRemove(this)
        }
    }
}

interface RemoveAnswerListener{
    fun onRemove(answer: Answer)
}

Dan jangan lupa untuk mereset posisi view yang masih berada diatas :

listAnswers.forEach {
    val view = it.view!!
    allWidth += (it.view?.width)?.toFloat()!! + 20F
    if (it == listAnswers.first()) {
        view.animate().x(0F)
    } else {
        allWidth -= view.width
        view.animate().x(allWidth)
    }
}

Dan sudah cukup begitu aja simple bukan? Yaps mudah — mudahab bisa menambah wawasan buat kalian yang ingin membuat animasi pada aplikasi android kalian. Jangan lupa bagikan tutorial ini kepada teman kalian yang lain semoga bermanfaat. Untuk source code silahkan download pada link di bawah ini :

https://github.com/ar-android/duolingo-view-move

Subscribe to My Newsletter

Thank you for your interest in my blog. Sign up to my newsletter to stay current on the latest news and information me and to be the first to see new blog posts.