Saya telah menemukan banyak contoh pertanyaan serupa pada SO tetapi sayangnya tidak ada jawaban yang memenuhi persyaratan saya.
Saya memiliki tata letak yang berbeda untuk potret dan lansekap dan saya menggunakan tumpukan belakang, yang keduanya mencegah saya menggunakan setRetainState()
dan trik menggunakan rutin perubahan konfigurasi.
Saya menunjukkan informasi tertentu kepada pengguna di TextViews, yang tidak disimpan di penangan default. Saat menulis aplikasi saya hanya menggunakan Aktivitas, yang berikut ini berfungsi dengan baik:
TextView vstup;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.whatever);
vstup = (TextView)findViewById(R.id.whatever);
/* (...) */
}
@Override
public void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
state.putCharSequence(App.VSTUP, vstup.getText());
}
@Override
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
vstup.setText(state.getCharSequence(App.VSTUP));
}
Dengan Fragment
s, ini hanya berfungsi dalam situasi yang sangat spesifik. Secara khusus, yang rusak adalah mengganti sebuah fragmen, meletakkannya di tumpukan belakang dan kemudian memutar layar ketika fragmen baru ditampilkan. Dari apa yang saya mengerti, fragmen lama tidak menerima panggilan onSaveInstanceState()
ketika diganti tetapi entah bagaimana tetap terhubung dengan Activity
dan metode ini dipanggil nanti ketika View
tidak ada lagi, jadi mencari salah satu TextView
hasil saya menjadi a NullPointerException
.
Juga, saya menemukan bahwa menjaga referensi ke saya TextViews
bukan ide yang baik dengan Fragment
s, bahkan jika tidak apa - apa dengan Activity
. Dalam hal ini, onSaveInstanceState()
sebenarnya menyelamatkan negara tetapi masalah muncul kembali jika saya memutar layar dua kali ketika fragmen disembunyikan, karena onCreateView()
itu tidak dipanggil dalam contoh baru.
Saya pikir menyelamatkan negara dalam onDestroyView()
ke dalam beberapa Bundle
-jenis unsur anggota kelas (itu sebenarnya lebih banyak data, bukan hanya satu TextView
) dan tabungan yang di onSaveInstanceState()
tetapi ada kelemahan lainnya. Terutama, jika fragmen yang saat ini ditampilkan, urutan memanggil dua fungsi dibalik, jadi saya akan perlu untuk account untuk dua situasi yang berbeda. Harus ada solusi yang lebih bersih dan benar!
Jawaban:
Untuk menyimpan keadaan instance dengan benar,
Fragment
Anda harus melakukan yang berikut:1. Dalam fragmen, simpan status instance dengan mengganti
onSaveInstanceState()
dan mengembalikanonActivityCreated()
:2. Dan poin penting , dalam aktivitas, Anda harus menyimpan instance fragmen
onSaveInstanceState()
dan mengembalikannyaonCreate()
.Semoga ini membantu.
sumber
Ini adalah cara yang saya gunakan saat ini ... ini sangat rumit tetapi setidaknya menangani semua situasi yang mungkin. Jika ada yang tertarik.
Atau , selalu ada kemungkinan untuk menjaga data ditampilkan
View
dalam variabel pasif s dan menggunakan dataView
hanya untuk menampilkannya, menjaga dua hal tetap sinkron. Saya tidak menganggap bagian terakhir sangat bersih.sumber
A
danB
, di manaA
saat ini di backstack danB
terlihat, maka Anda kehilangan statusA
(yang tidak terlihat) satu) jika Anda memutar layar dua kali . Masalahnya adalah bahwaonCreateView()
tidak dipanggil dalam skenario ini, hanya sajaonCreate()
. Jadi nanti, dionSaveInstanceState()
sana tidak ada pandangan untuk menyelamatkan negara. Seseorang harus menyimpan dan kemudian menyelamatkan negara lewatonCreate()
.App.VSTUP
danApp.STAV
keduanya adalah tag string yang mewakili objek yang mereka coba peroleh. Contoh:savedState = savedInstanceState.getBundle(savedGamePlayString);
atausavedState.getDouble("averageTime")
Di perpustakaan dukungan terbaru, tidak ada solusi yang dibahas di sini yang diperlukan lagi. Anda dapat bermain dengan
Activity
fragmen Anda sesuka Anda menggunakanFragmentTransaction
. Pastikan saja bahwa fragmen Anda dapat diidentifikasi dengan id atau tag.Fragmen akan dipulihkan secara otomatis selama Anda tidak mencoba membuatnya kembali pada setiap panggilan
onCreate()
. Sebagai gantinya, Anda harus memeriksa apakahsavedInstanceState
bukan nol dan menemukan referensi lama ke fragmen yang dibuat dalam kasus ini.Berikut ini sebuah contoh:
Namun perlu dicatat bahwa saat ini ada bug ketika memulihkan keadaan tersembunyi suatu fragmen. Jika Anda menyembunyikan fragmen dalam aktivitas Anda, Anda harus mengembalikan keadaan ini secara manual dalam kasus ini.
sumber
FragmentPagerAdapter
atauFragmentStatePagerAdapter
. Jika Anda melihat kodeFragmentStatePagerAdapter
, misalnya, Anda akan melihat bahwarestoreState()
metode mengembalikan fragmen dari yangFragmentManager
Anda berikan sebagai parameter saat membuat adaptor.Saya hanya ingin memberikan solusi yang saya temukan yang menangani semua kasus yang disajikan dalam posting ini yang saya dapatkan dari Vasek dan devconsole. Solusi ini juga menangani kasus khusus ketika ponsel diputar lebih dari satu kali sementara fragmen tidak terlihat.
Di sini adalah saya menyimpan bundel untuk digunakan kemudian karena onCreate dan onSaveInstanceState adalah satu-satunya panggilan yang dibuat ketika fragmen tidak terlihat
Karena destroyView tidak dipanggil dalam situasi rotasi khusus, kami dapat yakin bahwa jika itu menciptakan keadaan, kami harus menggunakannya.
Bagian ini akan sama.
Sekarang inilah bagian yang sulit. Dalam metode onActivityCreated saya, saya instantiate variabel "myObject" tetapi rotasi terjadi padaActivity dan onCreateView tidak dipanggil. Karenanya, myObject akan menjadi nol dalam situasi ini ketika orientasi berputar lebih dari satu kali. Saya menyiasatinya dengan menggunakan kembali bundel yang sama yang disimpan di onCreate sebagai bundel keluar.
Sekarang di mana pun Anda ingin mengembalikan negara hanya menggunakan bundel StateState
sumber
Berkat DroidT , saya membuat ini:
Saya menyadari bahwa jika Fragmen tidak mengeksekusi onCreateView (), pandangannya tidak instantiated. Jadi, jika fragmen di tumpukan belakang tidak membuat pandangannya, saya menyimpan status tersimpan terakhir, jika tidak, saya membangun bundel saya sendiri dengan data yang ingin saya simpan / pulihkan.
1) Perpanjang kelas ini:
2) Dalam Fragmen Anda, Anda harus memiliki ini:
3) Misalnya, Anda dapat memanggil hasSavedState di onActivityCreated:
sumber
sumber