Perbedaan antara add (), ganti (), dan addToBackStack ()

300

Apa perbedaan utama antara memanggil metode ini:

fragmentTransaction.addToBackStack(name);
fragmentTransaction.replace(containerViewId, fragment, tag);
fragmentTransaction.add(containerViewId, fragment, tag);

Apa artinya mengganti fragmen yang sudah ada, dan menambahkan fragmen ke status aktivitas, dan menambahkan aktivitas ke tumpukan belakang?

Kedua, dengan findFragmentByTag(), apakah pencarian untuk tag ini ditambahkan oleh metode add()/ replace()atau addToBackStack()metode?

AndroidDev
sumber

Jawaban:

331

1) fragmentTransaction.addToBackStack(str);

Deskripsi - Tambahkan transaksi ini ke tumpukan belakang. Ini berarti bahwa transaksi akan diingat setelah dilakukan, dan akan membalik operasinya ketika kemudian muncul dari tumpukan.

2) fragmentTransaction.replace(int containerViewId, Fragment fragment, String tag)

Deskripsi - Ganti fragmen yang ada yang ditambahkan ke wadah. Ini pada dasarnya sama dengan memanggil remove (Fragment) untuk semua fragmen yang saat ini ditambahkan yang ditambahkan dengan containerViewId yang sama dan kemudian tambahkan (int, Fragment, String) dengan argumen yang sama yang diberikan di sini.

3) fragmentTransaction.add(int containerViewId, Fragment fragment, String tag)

Deskripsi - Tambahkan fragmen ke status aktivitas. Fragmen ini secara opsional juga memiliki tampilan (jika Fragment.onCreateView mengembalikan non-null) ke tampilan wadah dari aktivitas.

Apa artinya mengganti fragmen yang sudah ada, dan menambahkan fragmen ke status aktivitas dan menambahkan aktivitas ke tumpukan belakang?

Ada tumpukan di mana semua kegiatan dalam keadaan berjalan disimpan. Fragmen milik aktivitas. Jadi, Anda dapat menambahkan mereka untuk menanamkannya dalam suatu aktivitas.

Anda dapat menggabungkan beberapa fragmen dalam satu aktivitas untuk membangun UI multi-pane dan menggunakan kembali fragmen dalam beberapa aktivitas. Ini pada dasarnya berguna ketika Anda telah mendefinisikan wadah fragmen Anda di tata letak yang berbeda. Anda hanya perlu mengganti dengan fragmen lain dalam tata letak apa pun.

Saat Anda menavigasi ke tata letak saat ini, Anda memiliki id wadah itu untuk menggantinya dengan fragmen yang Anda inginkan.

Anda juga dapat kembali ke fragmen sebelumnya di backStack dengan popBackStack()metode ini. Untuk itu Anda perlu menambahkan fragmen itu di stack menggunakan addToBackStack()dan kemudian commit()merefleksikannya. Ini dalam urutan terbalik dengan arus di atas.

findFragmentByTag apakah pencarian untuk tag ini ditambahkan oleh metode add / replace atau metode addToBackStack?

Jika tergantung pada bagaimana Anda menambahkan tag. Itu kemudian hanya menemukan sebuah fragmen dengan tag yang Anda tetapkan sebelumnya baik ketika dipompa dari XML atau seperti yang disediakan saat ditambahkan dalam transaksi.

Referensi: Transaksi Fragment

Tuhanku
sumber
2
Jadi, dapatkah saya menambahkan fragmen dengan mengganti metode pada aktivitas awal yang dimulai?
Yohanes AI
(Tidak ada fragmen ditambahkan sebelumnya)
Yohanes AI
2
Dapatkah wadah fragmen berisi lebih dari satu fragmen, Jika ya daripada bagaimana metode replace () akan berperilaku. Akankah ia mengganti semua frgamen dalam wadah atau api Android memiliki metode yang menerima tiga argumen, yaitu frgamentContainer, fragmen baru dan dengan siapa untuk mengganti.
ved
1
@ved Tidak, itu akan mengganti semua fragmen yang ada saat ini dalam wadah dengan yang sekarang.
reubenjohn
330

Satu lagi perbedaan penting antara adddan replaceini:

replacemenghapus fragmen yang ada dan menambahkan fragmen baru. Ini berarti ketika Anda menekan tombol kembali fragmen yang diganti akan dibuat dengan itu onCreateViewdipanggil. Sedangkan addmempertahankan fragmen yang ada dan menambahkan fragmen baru yang berarti fragmen yang ada akan aktif dan mereka tidak akan dalam keadaan 'dihentikan sementara' maka ketika tombol kembali ditekan onCreateViewtidak dipanggil untuk fragmen yang ada (fragmen yang ada di sana sebelum fragmen baru itu ditambahkan).

Dalam hal peristiwa siklus hidup fragmen onPause, onResume, onCreateViewdan peristiwa siklus hidup lainnya akan dipanggil dalam kasus replacetetapi mereka wont dipanggil dalam kasus add.

Sunting : Seseorang harus berhati-hati jika dia menggunakan semacam perpustakaan bus acara seperti Greenrobot's Eventbus dan menggunakan kembali fragmen yang sama untuk menumpuk fragmen di atas yang lain melalui add. Dalam skenario ini, meskipun Anda mengikuti praktik terbaik dan mendaftarkan bus peristiwa masuk onResumedan membatalkan pendaftaran onPause, bus peristiwa masih akan aktif di setiap contoh fragmen yang ditambahkan sebagai addfragmen tidak akan memanggil salah satu metode siklus hidup fragmen ini. Sebagai hasilnya, pendengar bus acara di setiap instance fragmen yang aktif akan memproses acara yang sama yang mungkin bukan yang Anda inginkan.

Astaga
sumber
1
Saya pikir salah satu pendekatan bisa memproses acara di fragmen paling atas dan memanggil cancelEventDelivery () setelah pemrosesan selesai. Anda dapat menemukan lebih banyak tentang metode cancelEventDelivery () di sini github.com/greenrobot/EventBus/blob/master/…
Jeevan
6
+1 dari saya. Sangat penting untuk mengetahui bahwa mengganti fragmen saat ini dengan fragmen baru, berarti fragmen sebelumnya akan dibuat ulang untuk mendapatkannya kembali ketika muncul kembali dari tumpukan fragmen.
AndaluZ
onPause, onResume sangat terkait dengan Aktivitas Host. Dan mereka tidak menelepon saat mengganti fragmen.
Zar E Ahmer
Hanya untuk menambahkan ini, jika Anda menggunakan EventBus Anda dapat menambahkan fragmen dengan Tag, dan meneruskan dari fragmen yang menandai ke acara tersebut, dan memeriksa pula, semua eventbus akan dipanggil, Anda cukup menentukan yang mana yang harus dijalankan
user2582318
Anda harus menyebutkan bahwa Anda memanggil metode addToBackStack () bersama dengan add () atau replace ().
rahil008
99

Contoh suatu kegiatan memiliki 2 fragmen dan kami menggunakan FragmentManageruntuk mengganti / menambahkan dengan addToBackstackmasing - masing fragmen ke tata letak dalam aktivitas

Gunakan ganti

Go Fragment1

Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume

Go Fragment2

Fragment2: onAttach
Fragment2: onCreate
Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment2: onCreateView
Fragment2: onActivityCreated
Fragment2: onStart
Fragment2: onResume

Fragmen Pop2

Fragment2: onPause
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
Fragment2: onDetach
Fragment1: onCreateView
Fragment1: onStart
Fragment1: onResume

Fragmen Pop1

Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach

Gunakan add

Go Fragment1

Fragment1: onAttach
Fragment1: onCreate
Fragment1: onCreateView
Fragment1: onActivityCreated
Fragment1: onStart
Fragment1: onResume

Go Fragment2

Fragment2: onAttach
Fragment2: onCreate
Fragment2: onCreateView
Fragment2: onActivityCreated
Fragment2: onStart
Fragment2: onResume

Fragmen Pop2

Fragment2: onPause
Fragment2: onStop
Fragment2: onDestroyView
Fragment2: onDestroy
Fragment2: onDetach

Fragmen Pop1

Fragment1: onPause
Fragment1: onStop
Fragment1: onDestroyView
Fragment1: onDestroy
Fragment1: onDetach

Proyek sampel

Phan Van Linh
sumber
1
tidak onPause()seharusnya dipanggil sebelumnya onStop()pada setiap aksi Pop ?
iCantC
jawaban yang bagus untuk membedakan antara 'add ()' dan 'replace ()', meskipun tidak ada tentang addToBackStack (). Upvote
Shirish Herwade
@ShirishHerwade Saya percaya dia menunjukkan perbedaan antara menambah dan mengganti dengan addToBackStack pada kedua kasus.
CyberShark
38

Meskipun ini adalah pertanyaan lama yang sudah dijawab, mungkin contoh-contoh berikut dapat melengkapi jawaban yang diterima dan mereka dapat berguna bagi beberapa programmer baru di Android seperti saya.

Opsi 1 - "addToBackStack ()" tidak pernah digunakan

Kasus 1A - menambah, menghapus, dan mengklik tombol Kembali

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
add Fragment C :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment B is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               App is closed, nothing is visible

Kasus 1B - menambah, mengganti, dan mengklik tombol Kembali

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
(replace Fragment C)    
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()
Fragment C :        onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               App is closed, nothing is visible

Opsi 2 - "addToBackStack ()" selalu digunakan

Kasus 2A - menambah, menghapus, dan mengklik tombol Kembali

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
add Fragment C :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView()                              Fragment B is visible
(Back button clicked)
Fragment C :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment C is visible
(Back button clicked)
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment B is visible
(Back button clicked)
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment A is visible
(Back button clicked)
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible

Kasus 2B - menambah, mengganti, menghapus, dan mengklik tombol Kembali

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
(replace Fragment C)    
Fragment B :        onPause() - onStop() - onDestroyView()  
Fragment A :        onPause() - onStop() - onDestroyView() 
Fragment C :        onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView()                              Activity is visible
(Back button clicked)
Fragment C :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment C is visible
(Back button clicked)
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onCreateView() - onActivityCreated() - onStart() - onResume()   
Fragment B :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment B is visible
(Back button clicked)
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment A is visible
(Back button clicked)
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible

Opsi 3 - "addToBackStack ()" tidak digunakan selalu (dalam contoh di bawah, w / o menunjukkan bahwa itu tidak digunakan)

Kasus 3A - menambah, menghapus, dan mengklik tombol Kembali

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B w/o:     onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
add Fragment C w/o:     onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Fragment B is visible
(Back button clicked)
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible

Kasus 3B - menambah, mengganti, menghapus, dan mengklik tombol Kembali

Activity :      onCreate() - onStart() - onResume()                             Activity is visible
add Fragment A :    onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment A is visible
add Fragment B w/o:     onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment B is visible
(replace Fragment C)    
Fragment B :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()   
Fragment A :        onPause() - onStop() - onDestroyView() 
Fragment C :        onAttach() - onCreate() - onCreateView() - onActivityCreated() - onStart() - onResume()     Fragment C is visible
remove Fragment C :     onPause() - onStop() - onDestroyView()                              Activity is visible
(Back button clicked)
Fragment C :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment C is visible
(Back button clicked)
Fragment C :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               
Fragment A :        onCreateView() - onActivityCreated() - onStart() - onResume()                   Fragment A is visible
(Back button clicked)
Fragment A :        onPause() - onStop() - onDestroyView() - onDestroy() - onDetach()               Activity is visible
(Back button clicked)
Activity :      onPause() - onStop() - onDestroy()                              App is closed, nothing is visible
Javi
sumber
1
Cukup menyeluruh. Usaha yang bagus!
pulp_fiction
Jadi dapatkah kita mengatakan bahwa ketika bekerja dengan tombol kembali fragmen bekerja dengan cara yang mirip dengan fungsi FragmentManager.popBackStack ()?
Tintin
jawaban yang bagus, tidak bisa lebih baik. Ini harus diterima jawaban.
Shirish Herwade
25

Perbedaan mendasar antara add()dan replace()dapat digambarkan sebagai:

  • add() digunakan untuk menambahkan fragmen ke beberapa elemen root.
  • replace() berperilaku serupa tetapi pada awalnya menghapus fragmen sebelumnya dan kemudian menambahkan fragmen berikutnya.

Kita dapat melihat perbedaan yang tepat ketika kita gunakan addToBackStack()bersama dengan add()atau replace().

Ketika kita menekan tombol kembali setelah dalam kasus add()... onCreateView tidak pernah dipanggil, tetapi dalam kasus replace(), ketika kita menekan tombol kembali ... oncreateView dipanggil setiap waktu.

Avanindra_dubey
sumber
1
Jadi apakah add () menghasilkan lebih banyak beban dalam hal memori android, karena tampilan fragmen sebelumnya tidak dihancurkan?
Derekyy
@ Serekyy Ya, saya kira begitu.
Arpit J.
adalah apa yang saya cari
parvez rafi
2

Ketika Kami Menambahkan Fragmen Pertama -> Fragmen Kedua menggunakan metode add ()

 btn_one.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(),"Click First 
Fragment",Toast.LENGTH_LONG).show();

                Fragment fragment = new SecondFragment();
                getActivity().getSupportFragmentManager().beginTransaction()
                        .add(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();
//                        .replace(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();

            }
        });

Saat kami menggunakan add () dalam fragmen

E/Keshav SecondFragment: onAttach
E/Keshav SecondFragment: onCreate
E/Keshav SecondFragment: onCreateView
E/Keshav SecondFragment: onActivityCreated
E/Keshav SecondFragment: onStart
E/Keshav SecondFragment: onResume

Saat kami menggunakan replace () dalam fragmen

pergi ke fragmen pertama ke fragmen kedua di Pertama -> Kedua menggunakan metode replace ()

 btn_one.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity(),"Click First Fragment",Toast.LENGTH_LONG).show();

                Fragment fragment = new SecondFragment();
                getActivity().getSupportFragmentManager().beginTransaction()
//                        .add(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();
                        .replace(R.id.fragment_frame, fragment, fragment.getClass().getSimpleName()).addToBackStack(null).commit();

            }
        });

E/Keshav SecondFragment: onAttach
E/Keshav SecondFragment: onCreate

E/Keshav FirstFragment: onPause -------------------------- FirstFragment
E/Keshav FirstFragment: onStop --------------------------- FirstFragment
E/Keshav FirstFragment: onDestroyView -------------------- FirstFragment

E/Keshav SecondFragment: onCreateView
E/Keshav SecondFragment: onActivityCreated
E/Keshav SecondFragment: onStart
E/Keshav SecondFragment: onResume

Dalam kasus Replace First Fragment, metode ini disebut ekstra (onPause, onStop, onDestroyView disebut ekstra)

E / Keshav FirstFragment: onPause

E / Keshav FirstFragment: onStop

E / Keshav FirstFragment: onDestroyView

Keshav Gera
sumber
0

Fungsi menambah dan mengganti FragmentManger dapat digambarkan sebagai 1. add ini berarti akan menambahkan fragmen dalam tumpukan kembali fragmen dan akan ditampilkan pada bingkai tertentu yang Anda sediakan seperti

getFragmentManager.beginTransaction.add(R.id.contentframe,Fragment1.newInstance(),null)

2.replace berarti Anda mengganti fragmen dengan fragmen lain pada frame yang diberikan

getFragmentManager.beginTransaction.replace(R.id.contentframe,Fragment1.newInstance(),null)

Utilitas utama di antara keduanya adalah bahwa ketika Anda kembali menumpuk, penggantian akan menyegarkan fragmen tetapi menambahkan tidak akan menyegarkan fragmen sebelumnya.

raj kavadia
sumber
0

Hal penting yang harus diperhatikan:

Perbedaan antara Ganti dan Ganti dengan backstack adalah setiap kali kita menggunakan hanya mengganti maka fragmen dihancurkan (ondestroy () dipanggil) dan ketika kita menggunakan ganti dengan backstack maka fragmen onDestroy () tidak disebut (yaitu ketika tombol kembali ditekan fragmen dipanggil dengan onCreateView ())

Lloyd Dcosta
sumber
0

Berikut adalah gambar yang menunjukkan perbedaan antara add()danreplace()

masukkan deskripsi gambar di sini

Jadi add()metode terus menambahkan fragmen di atas fragmen sebelumnya di FragmentContainer.

Sementara replace()metode menghapus semua Fragmen sebelumnya dari Kontainer dan kemudian menambahkannya di FragmentContainer.

Apa itu addToBackStack

addtoBackStackmetode dapat digunakan dengan add () dan ganti metode. Ini melayani tujuan yang berbeda di Fragment API.

Apa tujuannya?

API Fragmen tidak seperti API Aktivitas tidak datang dengan navigasi Tombol Kembali secara default. Jika Anda ingin kembali ke Fragmen sebelumnya maka kita menggunakan metode addToBackStack () di Fragment. Mari kita mengerti keduanya

Kasus 1:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .addToBackStack("TAG")
            .commit();

masukkan deskripsi gambar di sini

Kasus 2:

getSupportFragmentManager()
            .beginTransaction()
            .add(R.id.fragmentContainer, fragment, "TAG")
            .commit();

masukkan deskripsi gambar di sini

Rohit Singh
sumber