Layar pembuka

Android 12 menambahkan API SplashScreen yang memungkinkan animasi peluncuran aplikasi baru untuk semua aplikasi. Fitur ini meliputi gerakan ke dalam aplikasi saat peluncuran, layar pembuka yang menampilkan ikon aplikasi, dan transisi ke aplikasi itu sendiri.

Contoh layar pembuka
Gambar 1: Contoh layar pembuka

Pengalaman baru ini tidak hanya menghadirkan elemen desain standar ke setiap peluncuran aplikasi, melainkan juga elemen yang dapat disesuaikan sehingga aplikasi Anda dapat mempertahankan branding yang unik.

Cara kerja layar pembuka

Jika pengguna meluncurkan aplikasi saat proses aplikasi tidak berjalan (start cold) atau Aktivitas belum dibuat (start warm), peristiwa berikut akan terjadi. (Layar pembuka tidak pernah ditampilkan selama start hot.)

  1. Sistem menampilkan layar pembuka menggunakan tema dan animasi yang Anda tentukan.

  2. Setelah aplikasi siap, layar pembuka akan ditutup dan aplikasi ditampilkan.

Elemen dan mekanisme animasi

Elemen animasi ditentukan oleh file resource XML di Manifes Android. Setiap elemen memiliki versi mode terang dan gelap.

Setiap versi tersebut terdiri dari latar belakang jendela, ikon aplikasi animasi, dan latar belakang kon:

Elemen layar pembuka
Gambar 2: Elemen yang dapat disesuaikan dari layar pembuka

Perhatikan pertimbangan berikut terkait elemen ini:

  • Ikon aplikasi (1) harus merupakan vektor drawable, dan bisa statis atau animasi. Meskipun dapat memiliki durasi tak terbatas, sebaiknya animasi tidak melebihi 1.000 milidetik. Secara default, ikon peluncur digunakan.

  • Latar belakang ikon (2) bersifat opsional, dan berguna jika kontras diperlukan antara ikon dan latar belakang jendela. Jika Anda menggunakan ikon adaptif, latar belakangnya akan ditampilkan jika kontrasnya cukup dengan latar belakang jendela.

  • Seperti halnya ikon adaptif, ⅓ latar depan disamarkan (3).

  • Latar belakang jendela (4) terdiri dari satu warna buram. Jika latar belakang jendela ditetapkan dan berwarna polos, latar belakang ini akan digunakan secara default jika atribut tidak ditetapkan.

Mekanisme animasi layar pembuka terdiri dari animasi enter dan exit.

  • Animasi enter terdiri dari tampilan sistem ke layar pembuka. Animasi ini dikontrol oleh sistem dan tidak dapat disesuaikan.

  • Animasi exit terdiri dari animasi yang dijalankan yang menyembunyikan layar pembuka. Jika ingin menyesuaikannya, Anda harus memiliki akses ke SplashScreenView dan ikonnya serta dapat menjalankan animasi di situ menggunakan setelan transformasi, opasitas, dan warna. Dalam hal ini, layar pembuka harus dihapus secara manual jika animasi telah selesai.

Menyesuaikan layar pembuka di aplikasi Anda

Secara default, SplashScreen menggunakan windowBackground tema Anda jika berupa satu warna dan ikon peluncur. Penyesuaian layar pembuka dilakukan dengan menambahkan atribut ke tema aplikasi.

Layar pembuka aplikasi Anda dapat disesuaikan menggunakan salah satu cara berikut:

  • Menyetel atribut tema untuk mengubah tampilannya

  • Menyimpannya di layar untuk jangka waktu yang lebih lama

  • Menyesuaikan animasi untuk menutup layar pembuka

Menetapkan tema untuk layar pembuka untuk mengubah tampilannya

Anda dapat menentukan atribut berikut di tema Aktivitas untuk menyesuaikan layar pembuka aplikasi Anda. Jika Anda sudah memiliki implementasi layar pembuka yang lama dan telah menggunakan atribut seperti android:windowBackground, sebaiknya sediakan file resource alternatif untuk Android 12.

  1. Gunakan windowSplashScreenBackground untuk mengisi latar belakang dengan satu warna tertentu:

    <item name="android:windowSplashScreenBackground">@color/...</item>
    
  2. Gunakan windowSplashScreenAnimatedIcon untuk mengganti ikon di bagian tengah jendela mulai. Jika objek dapat dianimasikan dan dapat digambar melalui AnimationDrawable dan AnimatedVectorDrawable, objek tersebut juga akan memutar animasi saat menampilkan jendela awal.

    <item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>
    
  3. Gunakan windowSplashScreenAnimationDuration untuk menyetel frekuensi kemunculan layar pembuka sebelum ditutup. Waktu maksimum adalah 1.000 md.

  4. Gunakan windowSplashScreenIconBackground untuk menetapkan latar belakang di balik ikon layar pembuka. Ini berguna jika tidak ada cukup kontras antara latar belakang jendela dan ikon.

    <item name=”android:windowSplashScreenIconBackground”>@color/...</item>
    
  5. Anda juga dapat menggunakan windowSplashScreenBrandingImage untuk menyetel gambar agar ditampilkan di bagian bawah layar pembuka. Pedoman desain menyarankan untuk tidak menggunakan gambar brand.

    <item name=”android:windowSplashScreenBrandingImage”>@drawable/...</item>
    

Membiarkan layar pembuka tetap muncul di layar untuk waktu yang lebih lama

Layar pembuka ditutup setelah aplikasi Anda selesai menggambar frame pertamanya. Jika perlu memuat sedikit data seperti setelan tema dalam aplikasi dari disk lokal secara asinkron, Anda dapat menggunakan ViewTreeObserver.OnPreDrawListener untuk menangguhkan aplikasi menggambar bingkai pertamanya.

Kotlin

// Create a new event for the activity.
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Set the layout for the content view.
    setContentView(R.layout.main_activity)

    // Set up an OnPreDrawListener to the root view.
    val content: View = findViewById(android.R.id.content)
    content.viewTreeObserver.addOnPreDrawListener(
        object : ViewTreeObserver.OnPreDrawListener {
            override fun onPreDraw(): Boolean {
                // Check if the initial data is ready.
                return if (viewModel.isReady) {
                    // The content is ready; start drawing.
                    content.viewTreeObserver.removeOnPreDrawListener(this)
                    true
                } else {
                    // The content is not ready; suspend.
                    false
                }
            }
        }
    )
}

Java

// Create a new event for the activity.
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set the layout for the content view.
    setContentView(R.layout.main_activity);

    // Set up an OnPreDrawListener to the root view.
    final View content = findViewById(android.R.id.content);
    content.getViewTreeObserver().addOnPreDrawListener(
            new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    // Check if the initial data is ready.
                    if (mViewModel.isReady()) {
                        // The content is ready; start drawing.
                        content.getViewTreeObserver().removeOnPreDrawListener(this);
                        return true;
                    } else {
                        // The content is not ready; suspend.
                        return false;
                    }
                }
            });
}

Menyesuaikan animasi untuk menutup layar pembuka

Anda dapat menyesuaikan animasi layar pembuka lebih lanjut melalui Activity.getSplashScreen.

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // ...

    // Add a callback that's called when the splash screen is animating to
    // the app content.
    splashScreen.setOnExitAnimationListener { splashScreenView ->
        // Create your custom animation.
        val slideUp = ObjectAnimator.ofFloat(
            splashScreenView,
            View.TRANSLATION_Y,
            0f,
            -splashScreenView.height.toFloat()
        )
        slideUp.interpolator = AnticipateInterpolator()
        slideUp.duration = 200L

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.doOnEnd { splashScreenView.remove() }

        // Run your animation.
        slideUp.start()
    }
}

Java

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...

    // Add a callback that's called when the splash screen is animating to
    // the app content.
    getSplashScreen().setOnExitAnimationListener(splashScreenView -> {
        final ObjectAnimator slideUp = ObjectAnimator.ofFloat(
                splashScreenView,
                View.TRANSLATION_Y,
                0f,
                -splashScreenView.getHeight()
        );
        slideUp.setInterpolator(new AnticipateInterpolator());
        slideUp.setDuration(200L);

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                splashScreenView.remove();
            }
        });

        // Run your animation.
        slideUp.start();
    });
}

Pada awal callback ini, animasi vektor drawable pada layar pembuka telah dimulai. Bergantung pada durasi peluncuran aplikasi, drawable dapat berada di tengah animasinya. Gunakan SplashScreenView.getIconAnimationStartMillis untuk mengetahui kapan animasi dimulai. Anda dapat menghitung sisa durasi animasi ikon sebagai berikut:

Kotlin

// Get the duration of the animated vector drawable.
val animationDuration = splashScreenView.iconAnimationDurationMillis
// Get the start time of the animation.
val animationStart = splashScreenView.iconAnimationDurationMillis
// Calculate the remaining duration of the animation.
val remainingDuration = (
        animationDuration - (SystemClock.uptimeMillis() - animationStart)
    ).coerceAtLeast(0L)

Java

// Get the duration of the animated vector drawable.
long animationDuration = splashScreenView.getIconAnimationDurationMillis();
// Get the start time of the animation.
long animationStart = splashScreenView.getIconAnimationStartMillis();
// Calculate the remaining duration of the animation.
long remainingDuration = Math.max(
        animationDuration - (SystemClock.uptimeMillis() - animationStart),
        0L
);