Saya membuat aplikasi dengan Fragments
dan di salah satunya, saya membuat konstruktor non-default dan mendapat peringatan ini:
Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead
Dapatkah seseorang memberi tahu saya mengapa ini bukan ide yang baik?
Bisakah Anda menyarankan bagaimana saya akan mencapai ini:
public static class MenuFragment extends ListFragment {
public ListView listView1;
Categories category;
//this is my "non-default" constructor
public MenuFragment(Categories category){
this.category = category;
}....
Tanpa menggunakan konstruktor non-standar?
android
android-fragments
BlackHatSamurai
sumber
sumber
Jawaban:
Buat objek bundel dan masukkan data Anda (dalam contoh ini
Category
objek Anda ). Hati-hati, Anda tidak bisa melewatkan objek ini langsung ke bundel, kecuali serializable. Saya pikir lebih baik untuk membangun objek Anda dalam fragmen, dan hanya memasukkan id atau sesuatu yang lain ke dalam bundel. Ini adalah kode untuk membuat dan melampirkan bundel:Setelah itu, di data akses fragmen Anda:
Itu saja.
sumber
Parcelable
objek. Juga, Anda tidak harus lulusContext
, karena informasi yang dapat diakses melalui fragmengetActivity()
metode .Type value = getArguments().getType("key");
?newInstance()
metode. Sebagai contoh:public static FragmentName newInstance(your variables){}
. Seperti yang direkomendasikan oleh dokumentasi Android, jangan buat konstruktor dengan parameter, karena yang default (tanpa parameter) akan dipanggil secara otomatis setelah restart fragmen Anda.Sepertinya tidak ada jawaban yang benar-benar menjawab "mengapa menggunakan bundel untuk melewatkan parameter daripada konstruktor non default"
Alasan mengapa Anda harus melewati parameter melalui bundel adalah karena ketika sistem mengembalikan
fragment
(misalnya pada perubahan konfigurasi), itu akan secara otomatis mengembalikan Andabundle
.Panggilan balik suka
onCreate
atauonCreateView
harus membaca parameter daribundle
- dengan cara ini Anda dijamin untuk mengembalikan keadaan yangfragment
benar ke keadaan yang sama denganfragment
yang diinisialisasi dengan (perhatikan kondisi ini dapat berbeda darionSaveInstanceState bundle
yang diteruskan keonCreate/onCreateView
)Rekomendasi menggunakan
newInstance()
metode statis hanyalah rekomendasi. Anda dapat menggunakan konstruktor non default tetapi pastikan Anda mengisi parameter inisialisasi di bagianbundle
dalam tubuh konstruktor itu. Dan baca parameter-parameter tersebut di dalamonCreate()
atauonCreateView()
metode.sumber
Anda
Fragment
seharusnya tidak memiliki konstruktor karena bagaimanaFragmentManager
instantiasinya. Anda harus memilikinewInstance()
metode statis yang didefinisikan dengan parameter yang Anda butuhkan, lalu bundel dan setel sebagai argumen fragmen, yang nantinya dapat Anda akses denganBundle
parameter.Sebagai contoh:
Dan baca argumen ini di
onCreate
:Dengan cara ini, jika dilepaskan dan dilampirkan kembali, keadaan objek dapat disimpan melalui argumen, sangat mirip
bundles
denganIntent
s.sumber
Jika Anda menggunakan parameter untuk beberapa kelas. coba ini
sumber
FragmentManager
, Anda akan kehilangan mSomeInstance.Saya pikir, tidak ada perbedaan antara konstruktor statis dan dua konstruktor (kosong dan parametrik yang menyimpan argumen ke dalam bundel argumen Fragmen), kemungkinan besar, aturan praktis ini dibuat untuk mengurangi kemungkinan lupa untuk mengimplementasikan konstruktor no-arg di Jawa , yang tidak secara implisit dihasilkan saat kelebihan hadir.
Dalam proyek saya, saya menggunakan Kotlin, dan mengimplementasikan fragmen dengan konstruktor no-arg primer dan konstruktor sekunder untuk argumen yang hanya menyimpannya ke dalam bundel dan menetapkannya sebagai argumen Fragmen, semuanya berfungsi dengan baik.
sumber
Jika fragmen menggunakan konstruktor non-default setelah konfigurasi mengubah fragmen akan kehilangan semua data.
sumber