Penyematan aktivitas

Penyematan aktivitas mengoptimalkan aplikasi di perangkat layar besar dengan membagi jendela tugas aplikasi antara dua aktivitas atau dua instance aktivitas yang sama.

Gambar 1. Setelan aplikasi dengan aktivitas yang berdampingan.

Mengupdate codebase lama untuk mendukung layar berukuran besar membutuhkan banyak tenaga dan waktu. Konversi aplikasi berbasis aktivitas ke tata letak multipanel dengan menggunakan fragmen akan memerlukan pemfaktoran ulang yang signifikan.

Penyematan aktivitas memerlukan sedikit pemfaktoran ulang pada aplikasi Anda atau tidak sama sekali. Anda menentukan cara aplikasi menampilkan aktivitasnya, yaitu secara berdampingan atau ditumpuk, dengan membuat file konfigurasi XML atau dengan melakukan panggilan API Jetpack WindowManager.

Dukungan untuk layar kecil dikelola secara otomatis. Saat aplikasi Anda berada di perangkat yang memiliki layar berukuran kecil, aktivitas akan ditumpuk di atas aktivitas yang lain. Di layar besar, aktivitas akan ditampilkan secara berdampingan. Sistem menentukan presentasi berdasarkan konfigurasi yang telah Anda buat, dan tidak memerlukan logika cabang.

Penyematan aktivitas mendukung perubahan orientasi perangkat dan berfungsi dengan baik di perangkat foldable, aktivitas penumpukan dan pembongkaran saat perangkat dilipat dan dibentangkan.

Modern Android Development menggunakan arsitektur satu aktivitas dengan fragmen, komponen navigasi, dan pengelola tata letak serbaguna seperti SlidingPaneLayout.

Namun, jika aplikasi Anda terdiri dari beberapa aktivitas, penyematan aktivitas memungkinkan Anda dengan mudah memberikan pengalaman pengguna yang ditingkatkan di tablet, perangkat foldable, dan perangkat ChromeOS.

Jendela pemisahan tugas

Penyematan aktivitas memisahkan jendela tugas aplikasi menjadi dua penampung: primer dan sekunder. Penampung menyimpan aktivitas yang diluncurkan dari aktivitas utama atau dari aktivitas lain yang sudah ada di penampung.

Aktivitas ditumpuk di penampung sekunder saat diluncurkan, dan penampung sekunder ditumpuk di atas penampung utama pada layar kecil sehingga penumpukan aktivitas dan navigasi kembali konsisten dengan pengurutan aktivitas yang sudah ada di dalam aplikasi.

Dengan penyematan aktivitas tersebut, Anda menampilkan aktivitas dalam berbagai cara. Aplikasi Anda dapat memisahkan jendela tugas dengan meluncurkan dua aktivitas secara berdampingan:

Gambar 2. Dua aktivitas berdampingan.

Atau, aktivitas yang menempati seluruh jendela tugas dapat membuat pemisahan dengan meluncurkan aktivitas baru bersama:

Gambar 3. Aktivitas A memulai aktivitas B ke samping.

Aktivitas yang sudah dipisah dan berbagi jendela tugas dapat meluncurkan aktivitas lain dengan cara berikut:

  • Ke samping di atas aktivitas lain:

    Gambar 4. Aktivitas A memulai aktivitas C ke samping di atas aktivitas B.
  • Ke samping, dan menggeser pemisahan ke samping untuk menyembunyikan aktivitas utama yang sebelumnya:

    Gambar 5. Aktivitas B memulai aktivitas C ke samping dan menggeser pemisahan ke samping.
  • Meluncurkan aktivitas yang telah diterapkan di atas; yaitu, dalam tumpukan aktivitas yang sama:

    Gambar 6. Aktivitas B memulai aktivitas C tanpa tanda intent tambahan.
  • Meluncurkan jendela penuh aktivitas dalam tugas yang sama:

    Gambar 7. Aktivitas A atau aktivitas B memulai aktivitas C yang mengisi jendela tugas.

Navigasi kembali

Jenis aplikasi yang berbeda dapat memiliki aturan navigasi kembali yang berbeda pula dalam status jendela tugas terpisah, bergantung pada dependensi antara aktivitas atau cara pengguna memicu peristiwa kembali, misalnya:

  • Bersamaan: Jika aktivitas berkaitan, dan salah satunya tidak boleh ditampilkan tanpa pasangannya, navigasi kembali dapat dikonfigurasi untuk menyelesaikan keduanya.
  • Sendiri: Jika aktivitas sepenuhnya bersifat independen, navigasi kembali pada aktivitas tidak memengaruhi status aktivitas lain di jendela tugas.

Peristiwa kembali dikirim ke aktivitas yang terakhir difokuskan saat menggunakan navigasi tombol. Dengan navigasi berbasis gestur, peristiwa kembali dikirim ke aktivitas tempat gestur terjadi.

Tata letak multi-panel

Jetpack WindowManager 1.0 Beta03 memungkinkan Anda membuat tata letak multipanel yang berisi berbagai aktivitas di perangkat layar besar dengan 12L (API level 32) dan beberapa perangkat dengan versi platform lama. Aplikasi yang sudah ada berdasarkan beberapa aktivitas, bukan fragmen atau tata letak berbasis tampilan seperti SlidingPaneLayout dapat menghadirkan pengalaman pengguna yang lebih baik di layar besar tanpa pemfaktoran ulang yang signifikan.

Salah satu contoh umumnya adalah pemisahan detail daftar. Untuk memastikan presentasi yang berkualitas, sistem akan memulai aktivitas daftar, lalu aplikasi akan segera memulai aktivitas detail. Sistem transisi akan menunggu hingga kedua aktivitas digambar, lalu menampilkannya secara bersamaan. Bagi pengguna, kedua aktivitas tersebut akan diluncurkan sebagai satu aktivitas.

Gambar 8. Dua aktivitas dimulai secara bersamaan dalam tata letak multipanel.

Rasio pemisahan

Aplikasi Anda dapat menentukan cara jendela tugas disejajarkan dengan atribut ratio konfigurasi terpisah (lihat Konfigurasi terpisah di bawah).

Gambar 9. Dua pemisahan aktivitas dengan rasio pemisahan yang berbeda.

Placeholder

Aktivitas placeholder adalah aktivitas sekunder kosong yang menempati area pemisahan aktivitas. Tujuannya agar aktivitas kosong tersebut diganti dengan aktivitas lain yang berisi konten. Misalnya, aktivitas placeholder dapat menempatkan sisi sekunder aktivitas yang terpisah dalam tata letak detail daftar hingga item dari daftar dipilih, yang pada saat itu aktivitas berisi informasi detail daftar item terpilih akan menggantikan placeholder.

Placeholder hanya ditampilkan jika tersedia ruang untuk pemisahan. Anotasi ini otomatis akan selesai saat ukuran tampilan berubah menjadi lebar yang terlalu kecil untuk menampilkan pemisahan aktivitas, tetapi placeholder akan diluncurkan ulang secara otomatis (dengan status yang diinisialisasi ulang) jika ruangnya memungkinkan.

Gambar 10. Perangkat foldable terlipat dan terbuka. Aktivitas placeholder selesai dan dibuat ulang saat ukuran layar berubah.

Perubahan ukuran jendela

Saat perubahan konfigurasi perangkat mengurangi lebar jendela tugas sehingga tidak cukup besar untuk tata letak multipanel (misalnya, saat layar besar perangkat foldable dilipat dari semula ukuran tablet ke ukuran ponsel atau jendela aplikasi diubah ukurannya dalam mode multi-aplikasi), aktivitas non-placeholder di panel sekunder jendela tugas akan ditumpuk di atas aktivitas dalam panel utama.

Aktivitas placeholder hanya ditampilkan jika memiliki lebar tampilan yang cukup untuk pemisahan. Pada layar dengan ukuran lebih kecil, placeholder akan otomatis ditutup. Saat ukuran area layar menjadi cukup besar lagi, placeholder akan dibuat ulang. (Lihat Placeholder di atas.)

Penumpukan aktivitas dapat dilakukan karena WindowManager melakukan pengurutan z pada aktivitas di panel sekunder di atas aktivitas di panel utama.

Beberapa aktivitas di panel sekunder

Aktivitas B memulai aktivitas C tanpa tanda intent tambahan:

Pemisahan aktivitas yang berisi aktivitas A, B, dan C dengan C yang bertumpuk di
          atas B.

yang menghasilkan aktivitas urutan z berikut dalam tugas yang sama:

Tumpukan aktivitas sekunder yang berisi aktivitas C yang ditumpuk di atas B.
          Tumpukan sekunder ditumpuk di atas tumpukan aktivitas utama yang
          berisi aktivitas A.

Jadi, dalam jendela tugas yang lebih kecil, aplikasi akan dikecilkan satu aktivitas dengan C di bagian atas tumpukan:

Jendela kecil hanya menampilkan aktivitas C.

Kembali ke jendela yang lebih kecil akan membuka aktivitas yang ditumpuk di atas aktivitas yang lain.

Jika konfigurasi jendela tugas dikembalikan ke ukuran lebih besar yang dapat mengakomodasi beberapa panel, aktivitas akan ditampilkan lagi secara berdampingan.

Pemisahan bertumpuk

Aktivitas B memulai aktivitas C ke samping dan menggeser pemisahan ke samping:

Jendela tugas akan menampilkan aktivitas A dan B, lalu aktivitas B dan C.

Hasilnya adalah aktivitas urutan z berikut dalam tugas yang sama:

Aktivitas A, B, dan C dalam satu tumpukan. Aktivitas ditumpuk
          dalam urutan berikut dari atas ke bawah: C, B, A.

Pada jendela tugas yang lebih kecil, aplikasi akan dikecilkan ke satu aktivitas dengan C di bagian atas:

Jendela kecil hanya menampilkan aktivitas C.

Konfigurasi pemisahan

Penampung dan pemisahan dapat dibuat oleh library WindowManager berdasarkan aturan terpisah. Mengonfigurasi aturan terpisah memerlukan beberapa langkah:

  1. Tambahkan dependensi library WindowManager ke file build.gradle:

    implementation("androidx.window:window:1.0.0-beta03")

  2. Buat file resource yang melakukan hal berikut:

    • Menentukan aktivitas yang harus dipisahkan menggunakan filter
    • Mengonfigurasi opsi pemisahan untuk semua aktivitas yang berbagi pemisahan
    • Menentukan aktivitas yang tidak boleh ditempatkan dalam pemisahan

    Contoh:

    <!-- The split configuration for activities. -->
    <resources
        xmlns:window="http://schemas.android.com/apk/res-auto">
    
        <!-- Automatically split the following activity pairs. -->
        <SplitPairRule
            window:splitRatio="0.3"
            window:splitMinWidth="600dp"
            window:finishPrimaryWithSecondary="true"
            window:finishSecondaryWithPrimary="true">
            <SplitPairFilter
                window:primaryActivityName=".SplitActivityList"
                window:secondaryActivityName=".SplitActivityDetail"/>
            <SplitPairFilter
                window:primaryActivityName="*"
                window:secondaryActivityName="*/*"
                window:secondaryActivityAction="android.intent.action.VIEW"/>
        </SplitPairRule>
    
        <!-- Automatically launch a placeholder for the list activity. -->
        <SplitPlaceholderRule
            window:placeholderActivityName=".SplitActivityListPlaceholder"
            window:splitRatio="0.3"
            window:splitMinWidth="600dp">
            <ActivityFilter
                window:activityName=".SplitActivityList"/>
        </SplitPlaceholderRule>
    
    </resources>
    
  3. Memberi tahu definisi aturan ke library.

    Dalam contoh ini, kami menggunakan library Startup Jetpack untuk melakukan inisialisasi sebelum komponen lain dari aplikasi dimuat dan aktivitas dimulai. Untuk mengaktifkan fungsionalitas startup, tambahkan dependensi library di file build aplikasi:

    implementation("androidx.startup:startup-runtime:1.1.0")

    dan tambahkan entri berikut dalam manifes aplikasi:

    <!-- AndroidManifest.xml -->
    
    <provider android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:node="merge">
        <!-- This entry makes ExampleWindowInitializer discoverable. -->
        <meta-data  android:name="androidx.window.sample.embedding.ExampleWindowInitializer"
            android:value="androidx.startup" />
    </provider>
    
  4. Terakhir, tambahkan implementasi class penginisialisasi.

    Aturan ini ditetapkan dengan memberikan ID file resource xml yang berisi definisi (main_split_config) ke SplitController.initialize():

    Kotlin

    class ExampleWindowInitializer : Initializer<SplitController> {
       override fun create(context: Context): SplitController {
           SplitController.initialize(context, R.xml.main_split_config)
           return SplitController.getInstance(context)
       }
    
       override fun dependencies(): List<Class<out Initializer<*>>> {
           return emptyList()
       }
    }
    

    Java

    class ExampleWindowInitializer extends Initializer<SplitController> {
       @Override
       SplitController create(Context context) {
           SplitController.initialize(context, R.xml.main_split_config);
           return SplitController.getInstance(context);
       }
    
       @Override
       List<Class<? extends Initializer<?>>> dependencies() {
           return emptyList();
       }
    }
    

Contoh pemisahan

Memisahkan dari jendela penuh

Gambar 11. Aktivitas A memulai aktivitas B ke samping.

Tidak perlu memfaktorkan ulang. Anda dapat menentukan konfigurasi pemisahan secara statis atau saat runtime, lalu memanggil Context#startActivity() tanpa parameter tambahan.

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

Memisahkan secara default

Saat halaman landing aplikasi didesain untuk dibagi menjadi dua penampung pada layar besar, pengalaman pengguna akan optimal jika kedua aktivitas dibuat dan ditampilkan secara bersamaan. Namun, konten mungkin tidak tersedia untuk penampung sekunder pemisahan hingga pengguna berinteraksi dengan aktivitas di penampung utama (misalnya, pengguna memilih item dari menu navigasi). Aktivitas placeholder dapat mengisi kekosongan hingga konten dapat ditampilkan dalam penampung sekunder pemisahan (lihat Placeholder di atas).

Gambar 12. Pemisahan dibuat dengan membuka dua aktivitas secara bersamaan. Satu aktivitas adalah placeholder.

Untuk membuat pemisahan dengan placeholder, buat placeholder dan kaitkan dengan aktivitas utama:

<SplitPlaceholderRule
    window:placeholderIntentName=".Placeholder">
    <ActivityFilter
        window:activityName=".Main"/>
</SplitPlaceholderRule>

Saat aplikasi menerima intent, aktivitas target dapat ditampilkan sebagai bagian sekunder dari pemisahan aktivitas; Misalnya, permintaan untuk menampilkan layar detail dengan informasi tentang item dari suatu daftar. Di layar kecil, detail ditampilkan di jendela tugas penuh; pada perangkat yang lebih besar, ditampilkan di samping daftar.

Gambar 13. Aktivitas detail deep link ditampilkan sendiri di layar kecil, tetapi ditampilkan bersama dengan aktivitas daftar di layar besar.

Permintaan peluncuran harus diarahkan ke aktivitas utama, dan aktivitas detail target harus diluncurkan dalam pemisahan. SplitController otomatis memilih presentasi yang benar—ditumpuk atau berdampingan—berdasarkan lebar tampilan yang tersedia.

Kotlin

override fun onCreate(savedInstanceState Bundle?) {
    …
    splitController.registerRule(SplitPairRule(newFilters))
    startActivity(Intent(this, DetailActivity::class.java))
}

Java

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    …
    splitController.registerRule(new SplitPairRule(newFilters));
    startActivity(new Intent(this, DetailActivity.class));
}

Tujuan deep link mungkin satu-satunya aktivitas yang harus tersedia bagi pengguna di data navigasi sebelumnya, dan Anda mungkin tidak ingin mengabaikan aktivitas detail dan hanya menyisakan aktivitas utama:

Tampilan besar yang berisi aktivitas daftar dan detail aktivitas secara berdampingan.
          Navigasi kembali tidak dapat menutup aktivitas detail dan keluar dari
          aktivitas daftar di layar.

Layar kecil dengan aktivitas detail saja. Navigasi kembali tidak dapat
          menutup aktivitas detail dan menampilkan aktivitas daftar.

Sebagai gantinya, Anda dapat menyelesaikan kedua aktivitas secara bersamaan menggunakan atribut finishPrimaryWithSecondary:

<SplitPairRule
    window:finishPrimaryWithSecondary="true">
    <SplitPairFilter
        window:primaryActivityName=".List"
        window:secondaryActivityName=".Detail"/>
</SplitPairRule>

Beberapa aktivitas di penampung terpisah

Dengan penumpukan beberapa aktivitas dalam penampung terpisah, pengguna dapat mengakses konten yang dalam. Misalnya, dengan pemisahan detail daftar, mungkin pengguna harus membuka bagian sub-detail, tetapi tetap mempertahankan aktivitas utama:

Gambar 14. Aktivitas dibuka di panel sekunder jendela tugas.

Kotlin

class DetailActivity {
    …
    fun onOpenSubDetail() {
      startActivity(Intent(this, SubDetailActivity::class.java))
    }
}

Java

public class DetailActivity {
    …
    void onOpenSubDetail() {
        startActivity(new Intent(this, SubDetailActivity.class));
    }
}

Aktivitas sub-detail ditempatkan di atas aktivitas detail, dengan menyembunyikannya:

Pengguna kemudian dapat kembali ke tingkat detail sebelumnya dengan menavigasi kembali melalui tumpukan:

Gambar 15. Aktivitas dihapus dari bagian atas tumpukan.

Penumpukan aktivitas di atas aktivitas lain adalah perilaku default jika aktivitas diluncurkan dari aktivitas dalam penampung sekunder yang sama. Aktivitas yang diluncurkan dari pemisah utama dalam pemisahan aktif juga akan berakhir di pemisahan sekunder di bagian atas tumpukan aktivitas.

Aktivitas dalam tugas baru

Saat aktivitas di jendela tugas terpisah memulai aktivitas di tugas baru, tugas baru dipisahkan dari tugas yang menyertakan pemisahan dan ditampilkan sebagai jendela penuh. Layar Terbaru akan menampilkan dua tugas: tugas di pemisahan dan tugas baru.

Gambar 16. Memulai aktivitas C dalam tugas baru dari aktivitas B.

Penggantian aktivitas

Aktivitas dapat diganti di tumpukan penampung sekunder; misalnya, saat aktivitas utama digunakan untuk navigasi level atas dan aktivitas sekunder adalah tujuan yang dipilih. Setiap pilihan dari navigasi level atas harus memulai aktivitas baru di penampung sekunder dan menghapus satu atau beberapa aktivitas yang sebelumnya ada di penampung tersebut.

Gambar 17. Aktivitas navigasi level atas di panel utama menggantikan aktivitas tujuan di panel sekunder.

Jika aplikasi tidak menyelesaikan aktivitas dalam penampung sekunder ketika pilihan navigasi berubah, navigasi kembali mungkin akan membingungkan saat pemisahan diciutkan (saat perangkat dilipat). Misalnya, jika Anda memiliki menu di panel utama dan layar A dan B bertumpuk di panel sekunder, saat pengguna melipat ponsel, B berada di atas A, dan A berada di atas. Saat pengguna kembali dari B, A yang akan muncul, bukan menu.

Dalam kasus semacam ini, layar A harus dihapus dari data sebelumnya.

Perilaku default saat meluncurkan ke sisi dalam penampung baru selama pemisahan yang ada adalah menempatkan penampung sekunder baru di atas dan mempertahankan yang lama di data sebelumnya. Anda dapat mengonfigurasi pemisahan untuk menghapus penampung sekunder sebelumnya dengan clearTop dan meluncurkan aktivitas baru seperti biasa.

<SplitPairRule
    window:clearTop="true">
    <SplitPairFilter
        window:primaryActivityName=".Menu"
        window:secondaryActivityName=".ScreenA"/>
    <SplitPairFilter
        window:primaryActivityName=".Menu"
        window:secondaryActivityName=".ScreenB"/>
</SplitPairRule>

Kotlin

class MenuActivity {
    …
    fun onMenuItemSelected(selectedMenuItem: Int) {
        startActivity(Intent(this, classForItem(selectedMenuItem)))
    }
}

Java

public class MenuActivity {
    …
    void onMenuItemSelected(int selectedMenuItem) {
        startActivity(new Intent(this, classForItem(selectedMenuItem)));
    }
}

Atau, gunakan aktivitas sekunder yang sama, dan dari aktivitas utama (menu), kirimkan intent baru yang mengatasi instance yang sama, tetapi memicu status atau update UI di penampung sekunder.

Beberapa pemisahan

Aplikasi dapat menyediakan navigasi mendalam multi-level dengan meluncurkan aktivitas tambahan ke samping.

Saat aktivitas di penampung sekunder meluncurkan aktivitas baru ke samping, pemisahan baru akan dibuat di atas pemisahan yang ada.

Gambar 18. Aktivitas B memulai aktivitas C ke samping.

Data sebelumnya berisi semua aktivitas yang sebelumnya telah dibuka sehingga pengguna dapat menuju ke pemisahan A/B setelah menyelesaikan C.

Aktivitas A, B, dan C dalam tumpukan. Aktivitas ditumpuk dalam
          urutan berikut dari atas ke bawah: C, B, A.

Untuk membuat pemisahan baru, luncurkan aktivitas baru dari penampung sekunder yang ada ke samping. Deklarasikan konfigurasi untuk pemisahan A/B dan B/C dan luncurkan aktivitas C biasanya dari B:

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
    <SplitPairFilter
        window:primaryActivityName=".B"
        window:secondaryActivityName=".C"/>
</SplitPairRule>

Kotlin

class B {
    fun onOpenC() {
        startActivity(Intent(this, C::class.java))
    }
}

Java

public class B {
    …
    void onOpenC() {
        startActivity(new Intent(this, C.class));
    }
}

Merespons perubahan status pemisahan

Berbagai aktivitas dalam aplikasi dapat memiliki elemen UI yang melakukan fungsi yang sama; misalnya, kontrol yang membuka jendela yang berisi setelan akun.

Gambar 19. Berbagai aktivitas dengan elemen UI yang identik secara fungsional.

Akan berlebihan jika dua aktivitas yang memiliki elemen UI yang sama dipisah dan mungkin membingungkan untuk menampilkan elemen di kedua aktivitas.

Gambar 20. Duplikasi elemen UI dalam pemisahan aktivitas.

Untuk mengetahui waktu pemisahan aktivitas, daftarkan pemroses dengan SplitController untuk perubahan status terpisah. Kemudian, sesuaikan UI sesuai dengan:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    splitController
        .addSplitListener(this, mainThreadExecutor, SplitInfoChangeCallback())
}

inner class SplitInfoChangeCallback : Consumer<List<SplitInfo>> {
    override fun accept(splitInfoList: List<SplitInfo>) {
        findViewById<View>(R.id.infoButton).visibility =
            if (!splitInfoList.isEmpty()) View.GONE else View.VISIBLE
    }
}

Java

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    splitController
        .addSplitListener(this, mainThreadExecutor, SplitInfoChangeCallback());
}

class SplitInfoChangeCallback extends Consumer<List<SplitInfo>> {
    public void accept(List<SplitInfo> splitInfoList) {
        findViewById<View>(R.id.infoButton).visibility =
            !splitInfoList.isEmpty()) ? View.GONE : View.VISIBLE;
    }
}

Callback dapat dibuat dalam status siklus proses apa pun, termasuk saat suatu aktivitas dihentikan. Pemroses biasanya harus terdaftar di onStart() dan tidak terdaftar di onStop().

Modal jendela penuh

Beberapa aktivitas akan memblokir pengguna agar tidak berinteraksi dengan aplikasi hingga tindakan yang ditentukan dilakukan; misalnya, aktivitas layar login, layar konfirmasi kebijakan, atau pesan error. Aktivitas modal harus dicegah agar tidak muncul dalam pemisahan.

Suatu aktivitas dapat dipaksa untuk selalu mengisi jendela tugas menggunakan konfigurasi perluasan:

<ActivityRule
    window:alwaysExpand="true">
    <ActivityFilter
        window:activityName=".FullWidthActivity"/>
</ActivityRule>

Menyelesaikan aktivitas

Pengguna dapat menyelesaikan aktivitas di kedua sisi pemisahan dengan menggeser dari tepi layar:

Gambar 21. Gestur geser untuk menyelesaikan aktivitas B.
Gambar 22. Gestur geser untuk menyelesaikan aktivitas A.

Jika perangkat disiapkan untuk menggunakan tombol kembali, bukan navigasi gestur, input akan dikirim ke aktivitas yang difokuskan—aktivitas yang disentuh atau diluncurkan terakhir.

Hasil penyelesaian salah satu aktivitas dalam pemisahan bergantung pada konfigurasi pemisah.

Konfigurasi default

Jika satu aktivitas dalam pemisahan selesai, aktivitas yang tersisa akan menempati seluruh jendela:

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

Pemisahan yang berisi aktivitas A dan B. A selesai, menyisakan B yang menempati
          seluruh jendela.

Pemisahan yang berisi aktivitas A dan B. B selesai, menyisakan A yang menempati
          seluruh jendela.

Menyelesaikan aktivitas bersama

Selesaikan aktivitas utama secara otomatis jika aktivitas sekunder selesai:

<SplitPairRule
    window:finishPrimaryWithSecondary="true">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

Pemisahan yang berisi aktivitas A dan B. B selesai, yang juga
          menyelesaikan A, membuat jendela tugas menjadi kosong.

Pemisahan yang berisi aktivitas A dan B. A selesai, menyisakan hanya B
          di jendela tugas.

Selesaikan aktivitas sekunder secara otomatis saat aktivitas utama selesai:

<SplitPairRule
    window:finishSecondaryWithPrimary="true">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

Pemisahan yang berisi aktivitas A dan B. A selesai, yang juga
          menyelesaikan B, membuat jendela tugas menjadi kosong.

Pemisahan yang berisi aktivitas A dan B. B sudah selesai dan hanya menyisakan B
          di jendela tugas.

Selesaikan aktivitas bersama jika aktivitas utama atau sekunder selesai:

<SplitPairRule
    window:finishPrimaryWithSecondary="true"
    window:finishSecondaryWithPrimary="true">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

Pemisahan yang berisi aktivitas A dan B. A selesai, yang juga
          menyelesaikan B, membuat jendela tugas menjadi kosong.

Pemisahan yang berisi aktivitas A dan B. B selesai, yang juga
          menyelesaikan A, membuat jendela tugas menjadi kosong.

Menyelesaikan beberapa aktivitas dalam penampung

Jika beberapa aktivitas ditumpuk dalam penampung terpisah, menyelesaikan aktivitas di bagian bawah tumpukan tidak otomatis menyelesaikan aktivitas di bagian atas.

Misalnya, jika dua aktivitas berada dalam penampung sekunder, C di atas B:

Tumpukan aktivitas sekunder yang berisi aktivitas C yang ditumpuk di atas B
          ditumpuk di atas tumpukan aktivitas utama yang berisi aktivitas
          A.

dan konfigurasi pemisahan ditentukan oleh konfigurasi aktivitas A dan B:

<SplitPairRule>
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

menyelesaikan aktivitas teratas akan mempertahankan pemisahan.

Pisahkan dengan aktivitas A dalam penampung utama serta aktivitas B dan C di
          sekunder, C yang ditumpuk di atas B. C selesai, menyisakan A dan B dalam
          pemisahan aktivitas.

Menyelesaikan aktivitas bagian bawah (root) dari penampung sekunder tidak akan menghapus aktivitas di atasnya; dan, juga tetap akan mempertahankan pemisahan.

Pisahkan dengan aktivitas A dalam penampung utama serta aktivitas B dan C di
          sekunder, C yang ditumpuk di atas B. B selesai, menyisakan A dan C dalam
          pemisahan aktivitas.

Setiap aturan tambahan untuk menyelesaikan aktivitas secara bersamaan, seperti menyelesaikan aktivitas sekunder dengan aktivitas utama, juga akan dijalankan:

<SplitPairRule
    window:finishSecondaryWithPrimary="true">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

Pisahkan dengan aktivitas A dalam penampung utama serta aktivitas B dan C dalam
          penampung sekunder, C ditumpuk di atas B. A selesai, yang juga
          menyelesaikan B dan C.

Ketika pemisahan dikonfigurasi untuk menyelesaikan penampung primer dan sekunder sekaligus:

<SplitPairRule
    window:finishPrimaryWithSecondary="true"
    window:finishSecondaryWithPrimary="true">
    <SplitPairFilter
        window:primaryActivityName=".A"
        window:secondaryActivityName=".B"/>
</SplitPairRule>

Pisahkan dengan aktivitas A dalam penampung utama serta aktivitas B dan C di
          sekunder, C yang ditumpuk di atas B. C selesai, menyisakan A dan B dalam
          pemisahan aktivitas.

Pisahkan dengan aktivitas A dalam penampung utama serta aktivitas B dan C di
          sekunder, C yang ditumpuk di atas B. B selesai, menyisakan A dan C dalam
          pemisahan aktivitas.

Pisahkan dengan aktivitas A dalam penampung utama serta aktivitas B dan C di
          sekunder, C yang ditumpuk di atas B. A selesai, yang juga menyelesaikan B dan
          C.

Mengubah properti pemisahan saat runtime

Properti pemisahan yang saat ini aktif dan terlihat tidak dapat Anda ubah. Mengubah aturan pemisahan akan memengaruhi peluncuran aktivitas tambahan dan penampung baru, tetapi pemisahan yang sudah ada dan aktif tidak akan terpengaruh.

Untuk mengubah properti pemisahan aktif, selesaikan aktivitas samping atau aktivitas dalam pemisahan dan luncurkan lagi ke samping menggunakan konfigurasi baru.

Mengekstrak aktivitas dari pemisahan ke jendela penuh

Buat konfigurasi baru yang akan menampilkan jendela penuh aktivitas samping, lalu luncurkan kembali aktivitas dengan intent yang telah di-resolve ke instance yang sama.

Memeriksa dukungan pemisahan saat runtime

Penyematan aktivitas merupakan fitur 12L (API level 32), tetapi juga tersedia di beberapa perangkat dengan versi platform lama. Untuk memeriksa ketersediaan fitur pada runtime, gunakan metode SplitController.isSplitSupported():

Kotlin

val splitController = SplitController.Companion.getInstance()
if (splitController.isSplitSupported()) {
    // Device supports split activity features.
}

Java

SplitController splitController = SplitController.Companion.getInstance();
if (splitController.isSplitSupported()) {
  // Device supports split activity features.
}

Jika pemisahan tidak didukung, aktivitas akan diluncurkan di bagian atas (dengan mengikuti model reguler).

Batasan, pembatasan, dan peringatan

  • Hanya aplikasi host tugas yang diidentifikasi sebagai pemilik aktivitas root dalam tugas yang dapat mengatur dan menyematkan aktivitas lain dalam tugas. Jika aktivitas yang mendukung penyematan dan pemisahan berjalan di tugas milik aplikasi lain, penyematan dan pemisahan untuk aktivitas tersebut tidak akan berfungsi.
  • Aktivitas hanya dapat diatur dalam satu tugas. Meluncurkan aktivitas dalam tugas baru akan selalu menempatkannya di jendela baru yang diperluas di luar pemisahan yang ada.
  • Hanya aktivitas dalam proses sama yang dapat diatur dan dipisahkan. Callback SplitInfo hanya melaporkan aktivitas yang termasuk dalam proses yang sama karena tidak ada cara untuk mengetahui aktivitas dalam proses yang berbeda.
  • Setiap aturan aktivitas yang berpasangan atau tunggal hanya berlaku untuk peluncuran aktivitas yang terjadi setelah aturan didaftarkan. Saat ini, tidak ada cara untuk memperbarui pemisahan yang sudah ada ataupun properti visualnya.
  • Konfigurasi filter pasangan pemisahan harus cocok dengan intent yang digunakan saat meluncurkan seluruh aktivitas. Pencocokan terjadi pada saat aktivitas baru dimulai dari proses aplikasi sehingga mungkin tidak mengetahui nama komponen yang akan diselesaikan dalam proses sistem nantinya saat menggunakan intent implisit. Jika nama komponen tidak diketahui pada saat peluncuran, karakter pengganti dapat digunakan (“*/*”) dan pemfilteran dapat dilakukan berdasarkan tindakan intent.
  • Saat ini, tidak ada cara untuk memindahkan aktivitas antara penampung atau keluar-masuk pemisahan setelah dibuat. Pemisahan hanya dibuat oleh library WindowManager saat aktivitas baru dengan aturan yang cocok diluncurkan, dan pemisahan akan dihancurkan saat aktivitas terakhir dalam penampung terpisah telah selesai.
  • Aktivitas dapat diluncurkan ulang ketika konfigurasi berubah sehingga saat pemisahan dibuat atau dihapus dan batas aktivitas berubah, aktivitas dapat melewati penghancuran total instance sebelumnya dan pembuatan instance baru. Oleh karena itu, developer aplikasi harus berhati-hati dengan hal-hal seperti meluncurkan aktivitas baru dari callback siklus proses.

Referensi lainnya