Transaksi fragmen

Pada saat runtime, FragmentManager dapat menambahkan, menghapus, mengganti, dan melakukan tindakan lainnya dengan fragmen sebagai respons terhadap interaksi pengguna. Setiap kumpulan perubahan fragmen yang Anda commit disebut transaksi, dan Anda dapat menentukan tindakan yang harus dilakukan di dalam transaksi menggunakan API yang disediakan oleh class FragmentTransaction. Anda dapat mengelompokkan beberapa tindakan ke dalam satu transaksi, misalnya transaksi dapat menambahkan atau mengganti beberapa fragmen. Pengelompokan ini dapat berguna saat Anda memiliki beberapa fragmen setara yang ditampilkan di layar yang sama, seperti pada tampilan terpisah.

Anda dapat menyimpan setiap transaksi ke data sebelumnya yang dikelola oleh FragmentManager agar pengguna bisa mengarah mundur melewati perubahan fragmen (mirip dengan mengarah mundur melewati aktivitas).

Anda bisa mendapatkan instance FragmentTransaction dari FragmentManager dengan memanggil beginTransaction(), seperti yang ditunjukkan dalam contoh berikut:

Kotlin

val fragmentManager = ...
val fragmentTransaction = fragmentManager.beginTransaction()

Java

FragmentManager fragmentManager = ...
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

Panggilan terakhir pada setiap FragmentTransaction harus meng-commit transaksi. Panggilan commit() memberi sinyal ke FragmentManager bahwa semua operasi telah ditambahkan ke transaksi.

Kotlin

val fragmentManager = ...
// The fragment-ktx module provides a commit block that automatically
// calls beginTransaction and commit for you.
fragmentManager.commit {
    // Add operations here
}

Java

FragmentManager fragmentManager = ...
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

// Add operations here

fragmentTransaction.commit();

Mengizinkan perubahan penyusunan ulang status fragmen

Setiap FragmentTransaction harus menggunakan setReorderingAllowed(true):

Kotlin

supportFragmentManager.commit {
    ...
    setReorderingAllowed(true)
}

Java

FragmentManager fragmentManager = ...
fragmentManager.beginTransaction()
    ...
    .setReorderingAllowed(true)
    .commit();

Untuk kompatibilitas perilaku, flag penyusunan ulang tidak diaktifkan secara default. Namun, FragmentManager harus diizinkan untuk menjalankan FragmentTransaction dengan benar, terutama saat beroperasi pada data sebelumnya serta menjalankan animasi dan transisi. Mengaktifkan flag memastikan bahwa jika beberapa transaksi dijalankan secara bersamaan, fragmen perantara apa pun (yaitu yang ditambahkan dan kemudian segera diganti) tidak mengalami perubahan siklus proses atau menjalankan animasi atau transisinya. Perlu diperhatikan bahwa flag ini memengaruhi pelaksanaan awal transaksi dan membalikkan transaksi dengan popBackStack().

Menambah dan menghapus fragmen

Untuk menambahkan fragmen ke FragmentManager, panggil add() pada transaksi. Metode ini menerima ID penampung fragmen, serta nama class fragmen yang ingin ditambahkan. Fragmen yang ditambahkan dipindahkan ke status RESUMED. Sebaiknya penampung adalah FragmentContainerView yang merupakan bagian dari hierarki tampilan.

Untuk menghapus fragmen dari host, panggil remove(), dengan meneruskan instance fragmen yang diambil dari pengelola fragmen melalui findFragmentById() atau findFragmentByTag(). Jika tampilan fragmen sebelumnya ditambahkan ke penampung, tampilan akan dihapus dari penampung pada tahap ini. Fragmen yang dihapus dipindahkan ke status DESTROYED.

Gunakan replace() untuk mengganti fragmen yang ada dalam penampung dengan instance class fragmen baru yang Anda berikan. Memanggil replace() setara dengan memanggil remove() dengan fragmen dalam penampung dan menambahkan fragmen baru ke penampung yang sama tersebut.

Cuplikan kode berikut menunjukkan cara Anda dapat mengganti satu fragmen dengan fragmen lainnya:

Kotlin

// Create new fragment
val fragmentManager = // ...

// Create and commit a new transaction
fragmentManager.commit {
    setReorderingAllowed(true)
    // Replace whatever is in the fragment_container view with this fragment
    replace<ExampleFragment>(R.id.fragment_container)
}

Java

// Create new fragment and transaction
FragmentManager fragmentManager = ...
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setReorderingAllowed(true);

// Replace whatever is in the fragment_container view with this fragment
transaction.replace(R.id.fragment_container, ExampleFragment.class, null);

// Commit the transaction
transaction.commit();

Dalam contoh ini, instance baru ExampleFragment menggantikan fragmen, jika ada, yang saat ini terdapat dalam penampung tata letak yang diidentifikasi oleh R.id.fragment_container.

Secara default, perubahan yang dibuat dalam FragmentTransaction tidak ditambahkan ke data sebelumnya. Untuk menyimpan perubahan tersebut, Anda dapat memanggil addToBackStack() di FragmentTransaction. Untuk informasi selengkapnya, lihat Pengelola fragmen.

Commit bersifat asinkron

Memanggil commit() tidak langsung menjalankan transaksi. Sebaliknya, transaksi tersebut dijadwalkan untuk berjalan pada UI thread utama segera setelah dapat melakukannya. Namun, jika perlu, Anda dapat segera memanggil commitNow() untuk menjalankan transaksi fragmen pada UI thread.

Perhatikan bahwa commitNow tidak kompatibel dengan addToBackStack. Atau, Anda dapat menjalankan semua FragmentTransactions tertunda yang dikirimkan oleh panggilan commit() yang belum pernah dijalankan dengan memanggil executePendingTransactions(). Pendekatan ini kompatibel dengan addToBackStack.

Untuk sebagian besar kasus penggunaan, Anda hanya perlu commit().

Pengurutan operasi bersifat signifikan

Urutan Anda menjalankan operasi dalam FragmentTransaction bersifat signifikan, terutama saat menggunakan setCustomAnimations(). Metode ini menerapkan animasi yang diberikan ke semua operasi fragmen yang mengikutinya.

Kotlin

supportFragmentManager.commit {
    setCustomAnimations(enter1, exit1, popEnter1, popExit1)
    add<ExampleFragment>(R.id.container) // gets the first animations
    setCustomAnimations(enter2, exit2, popEnter2, popExit2)
    add<ExampleFragment>(R.id.container) // gets the second animations
}

Java

getSupportFragmentManager().beginTransaction()
        .setCustomAnimations(enter1, exit1, popEnter1, popExit1)
        .add(R.id.container, ExampleFragment.class, null) // gets the first animations
        .setCustomAnimations(enter2, exit2, popEnter2, popExit2)
        .add(R.id.container, ExampleFragment.class, null) // gets the second animations
        .commit()

Membatasi siklus proses fragmen

FragmentTransactions dapat memengaruhi status siklus proses fragmen individual yang ditambahkan dalam cakupan transaksi. Saat membuat FragmentTransaction, setMaxLifecycle() menetapkan status maksimum untuk fragmen yang diberikan. Misalnya, ViewPager2 menggunakan setMaxLifecycle() untuk membatasi fragmen di luar layar ke status STARTED.

Menampilkan dan menyembunyikan tampilan fragmen

Gunakan metode FragmentTransaction show() dan hide() untuk menampilkan dan menyembunyikan tampilan fragmen yang telah ditambahkan ke penampung. Metode ini menetapkan visibilitas tampilan fragmen tanpa memengaruhi siklus proses fragmen.

Meskipun Anda tidak perlu menggunakan transaksi fragmen untuk mengalihkan visibilitas tampilan dalam fragmen, metode ini berguna untuk kasus saat Anda ingin perubahan status visibilitas dikaitkan dengan transaksi di data sebelumnya.

Melampirkan dan melepaskan fragmen

Metode FragmentTransaction detach() melepaskan fragmen dari UI, sehingga menghancurkan hierarki tampilannya. Fragmen tersebut tetap dalam status yang sama (STOPPED) seperti saat ditempatkan di data sebelumnya. Ini berarti fragmen dihapus dari UI, tetapi masih dikelola oleh pengelola fragmen.

Metode attach() melampirkan kembali fragmen yang sebelumnya dilepas. Hal ini menyebabkan hierarki tampilannya dibuat ulang, yang dilampirkan ke UI, dan ditampilkan.

Karena FragmentTransaction diperlakukan sebagai kumpulan operasi atomik tunggal, panggilan ke detach dan attach pada instance fragmen yang sama dalam transaksi yang sama akan secara efektif membatalkan satu sama lain, sehingga menghindari penghancuran dan pembuatan ulang UI fragmen. Gunakan transaksi terpisah, yang dipisahkan dengan executePendingOperations() jika menggunakan commit(), jika Anda ingin melepaskan lalu segera melampirkan fragmen kembali.