0Pricing
Android Academy · Pelajaran

Animasi Gestur dan Pegas

Gerakan alami berbasis fisika.

Animasi Gestur dan Pegas adalah pelajaran Android Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Android Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Android Academy mencakup 4 pelajaran total.

Gerakan Fisik yang Interaktif

Animasi yang paling menyenangkan merespons jari pengguna dan terasa seperti benda nyata, dengan momentum dan pantulan. Untuk membuatnya, Anda menggabungkan gestur dengan animasi berbasis fisika.

Pelajaran ini membahas Animatable, pegas, peluruhan lemparan, dan pengaitannya dengan gestur seret untuk menghasilkan UI yang alami dan interaktif.

Animatable: Kontrol Tingkat Rendah

Sementara animate*AsState bereaksi terhadap status, Animatable memberi Anda kontrol imperatif. Anda menyimpannya dalam remember dan menggerakkannya dari coroutine dengan pemanggilan seperti animateTo atau snapTo.

Inilah dasar untuk gerakan yang dikendalikan gestur.

@Composable
fun BounceOnClick() {
    val scale = remember { Animatable(1f) }
    val scope = rememberCoroutineScope()
    Box(
        Modifier
            .graphicsLayer { scaleX = scale.value; scaleY = scale.value }
            .clickable {
                scope.launch {
                    scale.animateTo(1.3f, spring())
                    scale.animateTo(1f, spring())
                }
            }
    )
}

Pegas: dampingRatio & stiffness

Spesifikasi spring ditentukan oleh dua nilai:

  • dampingRatio - seberapa memantul. Nilai yang lebih rendah menghasilkan lebih banyak pantulan; 1f (teredam kritis) tidak melampaui target.
  • stiffness - seberapa cepat. Nilai yang lebih tinggi mencapai target dengan lebih cepat.

Compose menyediakan konstanta seperti Spring.DampingRatioMediumBouncy dan Spring.StiffnessLow, sehingga Anda jarang perlu menggunakan angka mentah.

val spec = spring<Float>(
    dampingRatio = Spring.DampingRatioLowBouncy,
    stiffness = Spring.StiffnessMedium
)

// later, inside a coroutine:
// offset.animateTo(targetValue = 0f, animationSpec = spec)

Mendeteksi Gestur Seret

Untuk membuat gerakan menjadi interaktif, Anda membaca input sentuhan. Modifier.pointerInput dengan detectDragGestures melaporkan perubahan posisi seretan saat pengguna menggerakkan jarinya.

Anda mengakumulasikan perubahan posisi tersebut ke dalam offset, lalu menerapkannya pada composable.

@Composable
fun Draggable() {
    var offsetX by remember { mutableStateOf(0f) }
    Box(
        Modifier
            .offset { IntOffset(offsetX.roundToInt(), 0) }
            .size(80.dp)
            .background(Color.Red)
            .pointerInput(Unit) {
                detectDragGestures { change, drag ->
                    change.consume()
                    offsetX += drag.x
                }
            }
    )
}

Kembali ke Posisi Semula dengan Pegas

Gabungkan seretan dengan Animatable untuk menghasilkan efek "kembali ke posisi semula". Saat diseret, Anda menggunakan snapTo untuk langsung memindahkan elemen ke posisi jari; saat dilepas, Anda menjalankan animateTo(0f) dengan pegas agar elemen memantul kembali ke posisi awal.

@Composable
fun SnapBack() {
    val offsetX = remember { Animatable(0f) }
    val scope = rememberCoroutineScope()
    Box(
        Modifier
            .offset { IntOffset(offsetX.value.roundToInt(), 0) }
            .size(80.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                detectDragGestures(
                    onDrag = { change, drag ->
                        change.consume()
                        scope.launch { offsetX.snapTo(offsetX.value + drag.x) }
                    },
                    onDragEnd = {
                        scope.launch { offsetX.animateTo(0f, spring()) }
                    }
                )
            }
    )
}

Lemparan dengan Kecepatan

Lemparan yang sebenarnya terus bergerak setelah jari terangkat. Lacak kecepatan dengan VelocityTracker, lalu teruskan ke animateDecay agar elemen meluncur hingga berhenti secara alami menggunakan DecayAnimationSpec berbasis gesekan.

val decay = rememberSplineBasedDecay<Float>()

// on drag end, with measured velocity:
// scope.launch {
//     offsetX.animateDecay(
//         initialVelocity = velocity,
//         animationSpec = decay
//     )
// }

Geser untuk Menutup dengan Jangkar

Untuk gestur geser dengan posisi berhenti yang tetap (seperti geser untuk menutup), anchoredDraggable akan berhenti di jangkar yang telah ditentukan. Anda mendeklarasikan status dan posisi pikselnya, lalu Compose menangani gerakan pegas di antara posisi-posisi tersebut.

enum class DragValue { Start, End }

val state = remember {
    AnchoredDraggableState(
        initialValue = DragValue.Start,
        anchors = DraggableAnchors {
            DragValue.Start at 0f
            DragValue.End at 300f
        }
    )
}

Animasi Tak Terbatas dan Berulang

Untuk gerakan berkelanjutan seperti titik berdenyut atau efek kilau pemuatan, gunakan rememberInfiniteTransition dengan infiniteRepeatable. Atur RepeatMode ke Reverse untuk gerakan bolak-balik, atau ke Restart untuk mengulang dari awal.

@Composable
fun Pulse() {
    val transition = rememberInfiniteTransition(label = "pulse")
    val scale by transition.animateFloat(
        initialValue = 1f,
        targetValue = 1.2f,
        animationSpec = infiniteRepeatable(
            animation = tween(700),
            repeatMode = RepeatMode.Reverse
        ),
        label = "scale"
    )
    Box(Modifier.graphicsLayer { scaleX = scale; scaleY = scale })
}

Menggabungkan Gestur dan Pegas

Pola interaktif yang khas: seret untuk memindahkan, lalu lepaskan untuk menstabilkan posisi. Lacak kecepatan selama seretan, lalu lakukan lemparan dengan animateDecay atau arahkan elemen ke jangkar dengan spring, bergantung pada jarak atau kecepatannya.

Inilah cara bottom sheet, carousel, dan kartu yang dapat ditutup terasa begitu alami.

// pattern:
// 1) onDrag    -> animatable.snapTo(current + delta)
// 2) onDragEnd -> if (fast) animatable.animateDecay(velocity, decay)
//                 else      animatable.animateTo(nearestAnchor, spring())

Stabilisasi Pegas dalam Kotlin Murni

Untuk merasakan cara kerja pegas saat mencapai posisi stabil, berikut loop Kotlin murni yang sederhana. Loop ini menerapkan gaya pemulih menuju target dan meredam kecepatan pada setiap langkah, dengan gagasan yang sama seperti yang dijalankan Compose pada setiap frame.

fun main() {
    var pos = 0f
    var vel = 0f
    val target = 200f
    val stiffness = 0.2f
    val damping = 0.75f
    repeat(8) { step ->
        vel = (vel + (target - pos) * stiffness) * damping
        pos += vel
        println("step $step pos=${"%.1f".format(pos)}")
    }
}

Ketuk, Tekan, dan Berbagai Gestur

Seretan bukan satu-satunya gestur. pointerInput juga menyediakan detectTapGestures untuk ketukan, ketukan ganda, dan tekan lama, serta detectTransformGestures untuk memperbesar dengan mencubit dan memutar.

Di sini, tekan lama memicu skala dengan pegas, dengan menggabungkan deteksi gestur dan Animatable.

@Composable
fun LongPressScale() {
    val scale = remember { Animatable(1f) }
    val scope = rememberCoroutineScope()
    Box(
        Modifier
            .graphicsLayer { scaleX = scale.value; scaleY = scale.value }
            .pointerInput(Unit) {
                detectTapGestures(
                    onLongPress = {
                        scope.launch { scale.animateTo(1.4f, spring()) }
                    },
                    onPress = {
                        tryAwaitRelease()
                        scope.launch { scale.animateTo(1f, spring()) }
                    }
                )
            }
    )
}

Pemeriksaan Singkat

Anda sedang membuat kartu yang dapat diseret dan harus memantul kembali ke titik asalnya saat dilepas. Kombinasi manakah yang sesuai dengan praktik Compose yang umum?

Rangkuman: Gestur dan Pegas

Sekarang Anda dapat membuat gerakan yang alami dan interaktif:

  • Animatable memberikan kontrol imperatif yang digerakkan coroutine melalui animateTo / snapTo.
  • spring disesuaikan dengan dampingRatio (pantulan) dan stiffness (kecepatan).
  • pointerInput + detectDragGestures mengubah sentuhan menjadi gerakan; animateDecay menambahkan lemparan.
  • anchoredDraggable berhenti di posisi tetap untuk interaksi geser.
  • rememberInfiniteTransition menggerakkan efek berulang seperti denyutan dan kilau.

Dengan ini, materi Animasi di Jetpack Compose selesai. Sekarang Anda dapat menganimasikan nilai, visibilitas, konten, dan gestur dengan percaya diri.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Animasi Gestur dan Pegas” gratis?

Ya — teks lengkap “Animasi Gestur dan Pegas” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Android Academy, upgrade ke CoddyKit PRO. Kursus Android Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Animasi Gestur dan Pegas”?

Gerakan alami berbasis fisika. Kamu berlatih Android Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Android Academy?

Tidak diperlukan pengalaman sebelumnya. Android Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Animasi Gestur dan Pegas” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Android Academy ini?

Ya. Setiap pelajaran Android Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mengapa Animasi Penting
  2. Dasar-Dasar animate*AsState
  3. AnimatedVisibility dan Transisi
  4. Animasi Gestur dan Pegas
← Kembali ke Android Academy