Menyimpan status dengan fragmen

Berbagai operasi sistem Android dapat memengaruhi status fragmen Anda. Untuk memastikan status pengguna disimpan, framework Android otomatis menyimpan serta memulihkan fragmen dan data sebelumnya. Oleh karena itu, Anda perlu memastikan bahwa setiap data dalam fragmen juga disimpan dan dipulihkan.

Tabel berikut menguraikan operasi yang menyebabkan fragmen Anda kehilangan status, serta apakah berbagai jenis status tetap ada melalui perubahan tersebut. Jenis status yang disebutkan dalam tabel adalah sebagai berikut:

  • Variables: variabel lokal dalam fragmen.
  • View State: setiap data yang dimiliki oleh satu tampilan atau lebih dalam fragmen.
  • SavedState: data yang melekat pada instance fragmen ini yang harus disimpan di onSaveInstanceState().
  • NonConfig: data yang diambil dari sumber eksternal, seperti server atau repositori lokal, atau data buatan pengguna yang dikirim ke server setelah di-commit.

Sering kali Variables diperlakukan sama dengan SavedState, tetapi tabel berikut membedakan keduanya untuk menunjukkan efek berbagai operasi pada keduanya.

Operasi Variables View State SavedState NonConfig
Ditambahkan ke data sebelumnya x
Perubahan Konfigurasi x
Penghentian/Pembuatan Ulang Proses x ✓*
Dihapus tidak ditambahkan ke data sebelumnya x x x x
Host selesai x x x x

* Status NonConfig dapat dipertahankan di seluruh penghentian proses menggunakan modul Status Tersimpan untuk ViewModel.

Tabel 1: Berbagai operasi penghancuran fragmen dan efek yang diberikan pada jenis status yang berbeda.

Mari kita lihat satu contoh spesifik. Pertimbangkan layar yang menghasilkan string acak, menampilkannya dalam TextView, dan memberikan opsi untuk mengedit string sebelum mengirimnya ke teman:

aplikasi generator teks acak yang menunjukkan berbagai
            jenis status
Gambar 1. Aplikasi generator teks acak yang menunjukkan berbagai jenis status.

Untuk contoh ini, asumsikan bahwa setelah pengguna menekan tombol edit, aplikasi akan menampilkan tampilan EditText tempat pengguna dapat mengedit pesan. Jika pengguna mengklik BATAL, tampilan EditText harus dihapus dan visibilitasnya ditetapkan ke View.GONE. Layar demikian mungkin memerlukan pengelolaan empat bagian data untuk memastikan pengalaman yang lancar:

Data Jenis Jenis Status Deskripsi
seed Long NonConfig Bibit yang digunakan untuk menghasilkan tindakan baik yang baru secara acak. Dihasilkan saat ViewModel dibuat.
randomGoodDeed String SavedState + Variable Dihasilkan saat fragmen dibuat untuk pertama kalinya. randomGoodDeed disimpan untuk memastikan pengguna melihat tindakan baik acak yang sama bahkan setelah penghentian dan pembuatan ulang proses.
isEditing Boolean SavedState + Variable Flag Boolean ditetapkan ke true bila pengguna mulai mengedit. isEditing disimpan untuk memastikan bahwa bagian pengeditan layar tetap terlihat saat fragmen dibuat ulang.
Teks yang diedit Editable View State (milik EditText) Teks yang diedit di tampilan EditText. Tampilan EditText menyimpan teks ini untuk memastikan bahwa perubahan yang sedang berjalan milik pengguna tidak hilang.

Tabel 2: Menyatakan bahwa aplikasi generator teks acak harus mengelola.

Bagian berikut menjelaskan cara mengelola status data Anda dengan tepat melalui operasi penghancuran.

View state

Tampilan bertanggung jawab untuk mengelola statusnya sendiri. Misalnya, saat tampilan menerima input pengguna, tampilan bertanggung jawab menyimpan dan memulihkan input tersebut guna menangani perubahan konfigurasi. Semua tampilan yang disediakan framework Android memiliki penerapan onSaveInstanceState() dan onRestoreInstanceState() sendiri, sehingga Anda tidak perlu mengelola status tampilan dalam fragmen.

Misalnya, dalam skenario sebelumnya, string yang diedit akan ada di EditText. EditText mengetahui nilai teks yang ditampilkan, serta detail lain, seperti bagian awal dan akhir teks yang dipilih.

Tampilan memerlukan ID untuk mempertahankan statusnya. ID ini harus unik dalam fragmen dan hierarki tampilannya. Tampilan tanpa ID tidak dapat mempertahankan statusnya.

<EditText
    android:id="@+id/good_deed_edit_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Seperti yang disebutkan dalam tabel 1, tampilan akan menyimpan dan memulihkan ViewState-nya melalui semua operasi yang tidak menghapus fragmen atau menghancurkan host.

SavedState

Fragmen Anda bertanggung jawab mengelola sejumlah kecil status dinamis yang integral dengan cara fragmen berfungsi. Anda dapat mempertahankan data yang diserialkan dengan mudah menggunakan Fragment.onSaveInstanceState(Bundle). Mirip dengan Activity.onSaveInstanceState(Bundle), data yang Anda tempatkan di paket ini dipertahankan melalui perubahan konfigurasi serta penghentian dan pembuatan ulang proses, selain itu tersedia di onCreate(Bundle) fragmen, onCreateView(LayoutInflater, ViewGroup, Bundle), dan metode onViewCreated(View, Bundle).

Melanjutkan contoh sebelumnya, randomGoodDeed adalah tindakan yang ditampilkan kepada pengguna, dan isEditing adalah flag untuk menentukan apakah fragmen tersebut menampilkan atau menyembunyikan EditText. Status tersimpan ini harus disimpan menggunakan onSaveInstanceState(Bundle), seperti yang ditunjukkan dalam contoh berikut:

Kotlin

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putBoolean(IS_EDITING_KEY, isEditing)
    outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed)
}

Java

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(IS_EDITING_KEY, isEditing);
    outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed);
}

Untuk memulihkan status di onCreate(Bundle), ambil nilai yang disimpan dari paket:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    isEditing = savedInstanceState?.getBoolean(IS_EDITING_KEY, false)
    randomGoodDeed = savedInstanceState?.getString(RANDOM_GOOD_DEED_KEY)
            ?: viewModel.generateRandomGoodDeed()
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        isEditing = savedInstanceState.getBoolean(IS_EDITING_KEY, false);
        randomGoodDeed = savedInstanceState.getString(RANDOM_GOOD_DEED_KEY);
    } else {
        randomGoodDeed = viewModel.generateRandomGoodDeed();
    }
}

Seperti yang dijelaskan dalam tabel 1, ingat bahwa variabel dipertahankan saat fragmen ditempatkan pada data sebelumnya. Memperlakukannya sebagai status tersimpan akan memastikannya tetap ada di semua operasi penghancuran.

NonConfig

Data NonConfig harus ditempatkan di luar fragmen, seperti dalam ViewModel. Pada contoh sebelumnya di atas, seed (status NonConfig) dihasilkan di ViewModel. Logika untuk mempertahankan statusnya dimiliki oleh ViewModel.

Kotlin

public class RandomGoodDeedViewModel : ViewModel() {
    private val seed = ... // Generate the seed

    private fun generateRandomGoodDeed(): String {
        val goodDeed = ... // Generate a random good deed using the seed
        return goodDeed
    }
}

Java

public class RandomGoodDeedViewModel extends ViewModel {
    private Long seed = ... // Generate the seed

    private String generateRandomGoodDeed() {
        String goodDeed = ... // Generate a random good deed using the seed
        return goodDeed;
    }
}

Class ViewModel memungkinkan data untuk bertahan dari perubahan konfigurasi, seperti rotasi layar, dan tetap tersimpan di memori saat fragmen ditempatkan di data sebelumnya. Setelah penghentian dan pembuatan ulang proses, ViewModel dibuat ulang, dan seed baru akan dibuat. Menambahkan modul SavedState ke ViewModel memungkinkan ViewModel mempertahankan status sederhana melalui penghentian dan pembuatan ulang proses.

Referensi lainnya

Untuk informasi selengkapnya tentang mengelola status fragmen, baca referensi tambahan berikut.

Codelab

Panduan