Transition: dasar-dasar, animasi transisi di aplikasi mobile

Penulis: IT Sectr Diterbitkan: 2026-03-02 Waktu membaca: 11 mnt

Transition (animasi transisi) — mekanisme perubahan visual dari satu konten ke konten lainnya: layar, fragmen, view, atau status antarmuka. Transisi yang diimplementasikan dengan benar mengarahkan perhatian pengguna, menjelaskan hubungan antar elemen, dan membuat navigasi menjadi intuitif. Menurut Material Design Guidelines (2026), aplikasi dengan transisi yang terencana menunjukkan retensi pengguna 22% lebih tinggi pada sesi kedua. Baca lebih lanjut tentang jenis animasi lainnya di panduan animasi umum.

Poin utama

  • Transition — animasi perubahan konten antar layar, fragmen, atau status.
  • UIView.transition — API utama untuk animasi transisi di iOS (UIKit).
  • FragmentTransaction.setCustomAnimations — konfigurasi animasi transisi antar Fragment di Android.
  • Transition Framework (android.transition) — sistem animasi deklaratif Android untuk transisi scene-ke-scene.
  • UIViewControllerAnimatedTransitioning — protokol iOS untuk transisi kustom antar controller.

Apa itu Transition?

Transition — adalah animasi yang terjadi ketika satu status visual antarmuka digantikan oleh yang lain. Berbeda dengan Property Animation (animasi properti satu objek), Transition mengelola seluruh rangkaian perubahan: kemunculan/penghilangan elemen, perubahan posisi, ukuran, dan propertinya dalam satu transisi. Transition memecahkan masalah perubahan konten yang mulus sehingga pengguna memahami apa yang berpindah ke mana.

Di platform mobile, Transition diterapkan dalam tiga skenario utama: navigasi antar layar (push, pop, modal present), pergantian fragmen (Android FragmentTransaction), dan perubahan status di dalam layar (memperluas kartu, mengganti tab). Setiap skenario memerlukan pendekatan sendiri: transisi navigasi — UIViewControllerAnimatedTransitioning di iOS atau ActivityOptions di Android, transisi intra-layar — Transition Framework atau UIView.transition.

Menurut Apple HIG (2026), durasi transisi standar tidak boleh melebihi 400–500 ms — animasi yang lebih lama dianggap sebagai keterlambatan. Material Design merekomendasikan 300–350 ms untuk transisi mobile. Untuk elemen besar (kartu, gambar), waktu dapat meningkat hingga 500–600 ms tanpa kehilangan kinerja yang dirasakan.

Jenis animasi transisi

Jenis transisi dibagi menjadi beberapa kategori tergantung pada konten apa yang berubah dan bagaimana. Tipe dasar: memudar (cross-fade) — penghilangan bertahap satu dan kemunculan yang lain; geser (slide) — satu layar pergi, yang lain datang; penskalaan (scale/zoom) — elemen membesar, membuka layar detail. Transisi gabungan menggabungkan beberapa efek.

Jenis transisiDeskripsiiOS APIAndroid API
Cross-fadeMemudar: satu konten menghilang, yang lain munculUIView.transition(with:duration:options:.transitionCrossDissolve)TransitionSet + Fade()
SlideGeser: konten pergi/datang secara horizontal atau vertikalCATransition(type: .push, subtype: .fromLeft)Slide() / FragmentTransaction.setCustomAnimations
Scale / ZoomPenskalaan: elemen membesar ke seluruh layarUIViewPropertyAnimator dengan animasi scaleScale() + ActivityOptions.makeScaleUpAnimation
ExplodeLedakan: konten berhamburan saat menghilangCATransition(type: .reveal)Explode() (API 21+)
Fade-throughMemudar melalui layar putih/hitamUIView.transition(with: .transitionCrossDissolve, dengan latar putih)Fade() melalui ChangeBounds

Aturan Material Design: gunakan satu jenis transisi dalam satu aplikasi untuk menciptakan bahasa visual yang seragam. Slide direkomendasikan untuk navigasi antar layar setara (master → detail), cross-fade untuk perubahan konten dalam satu layar (tab, pergantian tampilan), scale/zoom untuk transisi dari kartu ke layar detail (kartu produk → deskripsi).

Transition di iOS (Swift)

Di iOS UIView.transition adalah cara paling sederhana untuk menganimasikan perubahan konten dalam satu View. Mendukung cross-dissolve, curl-up, curl-down, flip-from-left, flip-from-right. Untuk transisi navigasi antar UIViewController, gunakan UINavigationControllerDelegate dengan UIViewControllerAnimatedTransitioning — ini memberikan kontrol penuh atas animasi push/pop.

swift
import UIKit

// UIView.transition: mengganti gambar dengan cross-dissolve
UIView.transition(with: imageView,
    duration: 0.4,
    options: [.transitionCrossDissolve, .curveEaseInOut]
) {
    self.imageView.image = UIImage(named: "new_image")
} completion: { _ in
    print("Transition selesai")
}

// UIView.transition: mengganti dua View
UIView.transition(from: firstView, to: secondView,
    duration: 0.5,
    options: [.transitionFlipFromRight, .showHideTransitionViews]
) { _ in
    // firstView disembunyikan, secondView ditampilkan
}

// CATransition untuk lapisan (tanpa Auto Layout)
let transition = CATransition()
transition.type = .push
transition.subtype = .fromRight
transition.duration = 0.35
transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
view.layer.add(transition, forKey: "pushTransition")

UIViewPropertyAnimator — alternatif modern untuk transisi kustom di iOS 10+. Tidak seperti UIView.transition, PropertyAnimator mendukung jeda, pembatalan, dan reverse (animasi terbalik), yang penting untuk transisi interaktif (swipe-to-go-back). Untuk animasi antar UIViewController, gunakan UIPercentDrivenInteractiveTransition bersama PropertyAnimator — ini adalah pola standar untuk navigasi interaktif.

Transition di Android (Kotlin)

Di Android FragmentTransaction dengan setCustomAnimations adalah cara utama menganimasikan transisi antar Fragment. Parameter: enter (animasi masuk Fragment baru), exit (animasi keluar Fragment lama), popEnter dan popExit — untuk navigasi mundur. FragmentTransaction mendukung animasi sumber daya (R.anim) dan Transition Framework (R.transition).

kotlin
import androidx.fragment.app.FragmentTransaction
import androidx.transition.TransitionInflater

// FragmentTransaction dengan animasi sumber daya
supportFragmentManager.beginTransaction()
    .setCustomAnimations(
        R.anim.slide_in_right,  // enter
        R.anim.slide_out_left,  // exit
        R.anim.slide_in_left,   // popEnter
        R.anim.slide_out_right  // popExit
    )
    .replace(R.id.container, DetailFragment())
    .addToBackStack(null)
    .commit()

// FragmentTransaction dengan Transition Framework
val detailFragment = DetailFragment()
detailFragment.enterTransition = TransitionInflater.from(this)
    .inflateTransition(R.transition.slide_right)
detailFragment.exitTransition = TransitionInflater.from(this)
    .inflateTransition(R.transition.fade_out)

supportFragmentManager.beginTransaction()
    .replace(R.id.container, detailFragment)
    .addToBackStack(null)
    .commit()

// ActivityOptions: animasi saat memulai Activity
val options = ActivityOptions.makeScaleUpAnimation(
    view, 0, 0, view.width, view.height
).toBundle()
startActivity(intent, options)

Praktik terbaik Android: Slide() — untuk mengganti Fragment dalam navigasi (enter = Slide(Gravity.END), exit = Slide(Gravity.START)). Fade() — untuk menampilkan/menyembunyikan overlay dan dialog. Explode() — untuk transisi aksen (menghapus elemen dari daftar). Untuk perangkat lama (API < 21) gunakan R.anim sebagai fallback. Transition Framework tidak mendukung SurfaceView, TextureView, GLSurfaceView — untuk video dan kamera gunakan hanya animasi melalui R.anim.

Transisi UIViewController kustom di iOS

UIViewControllerAnimatedTransitioning — protokol iOS untuk membuat animasi transisi yang sepenuhnya kustom antar controller. Memberikan akses ke View kontainer (transitionContext.containerView), View sumber dan tujuan. Dalam kombinasi dengan UIPercentDrivenInteractiveTransition, pendekatan ini memungkinkan pembuatan transisi interaktif dengan gesekan jari.

swift
import UIKit

"> Animator transisi kustom
class ScaleTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    let isPresenting: Bool

    init(presenting: Bool) { self.isPresenting = presenting }

    func transitionDuration(using ctx: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.4
    }

    func animateTransition(using ctx: UIViewControllerContextTransitioning) {
        guard let toView = ctx.view(forKey: .to),
              let fromView = ctx.view(forKey: .from)
        else { return }

        let container = ctx.containerView
        let initialScale: CGAffineTransform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        let finalFrame = ctx.finalFrame(for: toView)

        if isPresenting {
            toView.transform = initialScale
            toView.alpha = 0
            toView.frame = finalFrame
            container.addSubview(toView)
        }

        UIView.animate(withDuration: transitionDuration(using: ctx),
                       delay: 0,
                       usingSpringWithDamping: 0.7,
                       initialSpringVelocity: 0.3) {
            if self.isPresenting {
                toView.transform = .identity
                toView.alpha = 1
                fromView.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
                fromView.alpha = 0
            } else {
                fromView.transform = initialScale
                fromView.alpha = 0
            }
        } completion: { _ in
            fromView.transform = .identity
            ctx.completeTransition(!ctx.transitionWasCancelled)
        }
    }
}

// Penerapan di UINavigationControllerDelegate
extension MainViewController: UINavigationControllerDelegate {
    func navigationController(
        _ nc: UINavigationController,
        animationControllerFor operation: UINavigationController.Operation,
        from: UIViewController, to: UIViewController
    ) -> UIViewControllerAnimatedTransitioning? {
        return ScaleTransitionAnimator(presenting: operation == .push)
    }
}

Transisi interaktif: tambahkan UIPanGestureRecognizer ke layar sumber. Saat gestur terpicu, buat UIPercentDrivenInteractiveTransition dan panggil update(CGFloat(percent)). Untuk pembatalan saat tidak mencapai ambang (biasanya 30%), panggil cancel(). Pola ini digunakan secara default di UINavigationController pada gestur pop dan di UIScrollView dengan pagingEnabled. Untuk gestur kustom, implementasikan UIViewControllerInteractiveTransitioning.

Transition Framework di Android: scene ke scene

Transition Framework (android.transition) — adalah sistem animasi deklaratif yang secara otomatis menganimasikan perubahan antara dua scene (Scene). Scene adalah kumpulan View dengan status tertentu. Saat transisi dari Scene A ke Scene B, Transition Framework menganalisis perbedaan dan menganimasikan: perubahan posisi (ChangeBounds), perubahan ukuran (ChangeClipBounds, ChangeTransform), kemunculan (Fade), dan penghilangan (Fade).

kotlin
import android.transition.Scene
import android.transition.TransitionManager
import android.transition.TransitionSet
import android.transition.AutoTransition
import android.transition.ChangeBounds
import android.transition.Fade

// TransitionSet: kombinasi ChangeBounds + Fade
val transition = TransitionSet().apply {
    ordering = TransitionSet.ORDERING_TOGETHER
    addTransition(ChangeBounds())
    addTransition(Fade(Fade.IN))
    duration = 400L
    interpolator = FastOutSlowInInterpolator()
}

// Transisi antar scene di ViewGroup
val sceneRoot = findViewById<ViewGroup>(R.id.scene_root)
val scene1 = Scene.getSceneForLayout(sceneRoot, R.layout.scene_initial)
val scene2 = Scene.getSceneForLayout(sceneRoot, R.layout.scene_expanded)

"> AutoTransition tanpa konfigurasi manual
TransitionManager.go(scene2, AutoTransition().apply {
    duration = 350L
})

// TransitionManager.beginDelayedTransition — tanpa scene
TransitionManager.beginDelayedTransition(sceneRoot, ChangeBounds())
itemView.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
itemView.requestLayout() "> Perubahan layout dianimasikan secara otomatis

ChangeBounds — transisi paling sering digunakan di Android, menganimasikan perubahan posisi dan ukuran View. ChangeTransform menganimasikan rotation dan scale. ChangeImageTransform — untuk animasi ImageView (centerCrop → fitCenter). Untuk transisi kompleks dengan perubahan struktur hierarki, gunakan TransitionSet dengan ordering = ORDERING_SEQUENTIAL (animasi dijalankan secara berurutan, tidak paralel). Menurut dokumentasi Android Developers (2026), Transition Framework mendukung semua View standar, tetapi tidak mendukung animasi permukaan (SurfaceView, TextureView, VideoView).

Pertanyaan yang sering diajukan

Apa perbedaan antara Transition dan Animation?

Animation — animasi properti satu objek (alpha, translation, scale). Transition — animasi perubahan kumpulan objek atau status (fragment → fragment, scene → scene). Transition mengelola banyak perubahan secara simultan: kemunculan, penghilangan, perpindahan, perubahan ukuran — dan secara otomatis menganimasikan perbedaan antara dua status. Animation memerlukan pengelolaan manual setiap properti.

Bagaimana cara membuat transisi mulus antar fragmen Android?

Gunakan FragmentTransaction.setCustomAnimations dengan Transition Framework: fragment1.exitTransition = Fade(Fade.OUT), fragment2.enterTransition = Slide(Gravity.END). Untuk urutan: setReorderingAllowed(true) — fragmen akan diurutkan ulang untuk transisi paralel yang mulus. Untuk kasus sederhana, slide_in_right / slide_out_left dari R.anim sudah cukup. Untuk navigasi mundur, tentukan popEnter dan popExit.

Transition Framework tidak menganimasikan perubahan tinggi View — apa yang harus dilakukan?

Transition Framework hanya menganimasikan properti yang tidak menyebabkan perhitungan ulang layout. Untuk animasi tinggi, gunakan ChangeBounds — secara otomatis menganimasikan perubahan batas View antara dua status layout. Panggil TransitionManager.beginDelayedTransition(viewGroup, ChangeBounds()) sebelum mengubah LayoutParams. Jika tinggi berubah melalui WRAP_CONTENT, pastikan layout_height sebelum dan sesudah berbeda — ChangeBounds tidak akan berfungsi jika kedua status adalah match_parent.

Bagaimana cara membuat transisi kustom di SwiftUI?

Gunakan modifier .transition() dengan AnyTransition: .transition(.move(edge: .trailing).combined(with: .opacity)). Untuk transisi kustom, implementasikan AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)). Untuk animasi di dalam NavigationStack, gunakan .navigationTransition(.slide) di iOS 18+. SwiftUI tidak mendukung UIViewControllerAnimatedTransitioning — hanya transisi deklaratif melalui AnyTransition.

Bagaimana cara mengukur kinerja Transition?

Gunakan Profile GPU Rendering (Android) atau Core Animation Instrument (iOS). Untuk Android, tambahkan profiling Transition melalui adb shell setprop debug.transition.profiling 1 — di log akan muncul durasi setiap tahap transisi. Di iOS, aktifkan Slow Animations di simulator. Metrik target: durasi < 400 ms, FPS >= 55, frame drops — tidak lebih dari 2 per transisi. Untuk scene kompleks dengan 15+ View yang dianimasikan secara simultan, gunakan ChangeBounds dengan duration 300 ms.

Ringkasan

  • Transition — animasi perubahan konten antar layar, fragmen, atau status antarmuka.
  • UIView.transition (iOS) — API dasar untuk transisi cross-dissolve, flip, curl di dalam View.
  • UIViewControllerAnimatedTransitioning (iOS) — protokol untuk transisi kustom antar controller.
  • FragmentTransaction.setCustomAnimations (Android) — animasi transisi antar Fragment.
  • Transition Framework (android.transition) — sistem scene deklaratif: ChangeBounds, Fade, Slide, Explode.
  • Durasi yang direkomendasikan: 300–400 ms untuk mobile, hingga 600 ms untuk elemen besar.
  • Satu jenis transisi per aplikasi untuk bahasa visual yang seragam (Material Design).

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga