Add (), replace () ve addToBackStack () arasındaki fark


300

Bu yöntemleri çağırmak arasındaki temel fark nedir:

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

Mevcut bir parçayı değiştirmek ve etkinlik durumuna bir parça eklemek ve arka yığını bir etkinlik eklemek ne anlama gelir?

İkincisi, ile / yöntemi veya yöntem findFragmentByTag()tarafından eklenen etiketi arar mı?add()replace()addToBackStack()

Yanıtlar:


331

1) fragmentTransaction.addToBackStack(str);

Açıklama - Bu işlemi arka yığını ekleyin. Bu, işlem tamamlandıktan sonra hatırlanacak ve daha sonra yığına atıldığında çalışmasını tersine çevireceği anlamına gelir.

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

Açıklama - Bir kaba eklenen mevcut bir parçayı değiştirin. Bu esasen, aynı containerViewId ile eklenen ve sonra da aynı argümanlarla eklenen (int, Fragment, String) şu anda eklenen tüm parçalar için remove (Fragment) çağrılmasıyla aynıdır.

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

Açıklama - Etkinlik durumuna bir parça ekleyin. Bu parça isteğe bağlı olarak, etkinliğin kapsayıcı görünümünde de (Fragment.onCreateView boş değilse) görünümüne sahip olabilir.

Mevcut bir parçayı değiştirmek ve etkinlik durumuna bir parça eklemek ve arka yığını bir etkinlik eklemek ne anlama gelir?

Çalışan durumdaki tüm etkinliklerin tutulduğu bir yığın var. Parçalar etkinliğe aittir. Böylece bunları bir etkinliğe katmak için ekleyebilirsiniz.

Çok bölmeli kullanıcı arayüzü oluşturmak ve bir parçayı birden çok etkinlikte yeniden kullanmak için birden çok parçayı tek bir etkinlikte birleştirebilirsiniz. Bu, parça kabınızı farklı mizanpajlarda tanımladığınızda çok kullanışlıdır. Herhangi bir düzende başka bir parça ile değiştirmeniz yeterlidir.

Geçerli düzene gittiğinizde, onu istediğiniz parçayla değiştirmek için o kabın kimliğine sahip olursunuz.

Ayrıca popBackStack()yöntemle backStack'taki önceki parçaya geri dönebilirsiniz . Bunun için addToBackStack()ve sonra commit()yansıtmak için o parçayı yığına eklemeniz gerekir . Bu, akım üstte olacak şekilde ters sıradadır.

findFragmentByTag bu ekle / değiştir yöntemi veya addToBackStack yöntemi tarafından eklenen etiketi arar?

Etiketi nasıl eklediğinize bağlı olarak değişir. Daha sonra, XML'den şişirildiğinde veya bir işleme eklenirken sağlandığı şekilde daha önce tanımladığınız etiketine göre bir parça bulur.

Kaynaklar: FragmentTransaction


2
Peki, başlatılan başlangıç ​​etkinliğinde replace yöntemiyle parça ekleyebilir miyim?
Yohanes AI

(Daha önce fragman eklenmedi)
Yohanes AI

2
Bir fragman kabı birden fazla fragman içerebilir mi, evet ise replace () yöntemi nasıl davranır. Bu kapsayıcıdaki veya android api'deki tüm frgamentlerin yerini alacak mı? FrgamentContainer, yeni parça ve kimin değiştirileceği üç argümanı kabul eden bir yöntem var.
ved

1
@ved Hayır, kapta mevcut olan tüm parçaları geçerli olanla değiştirir.
reubenjohn

330

Arasında Bir daha önemli fark addve replaceşudur:

replacevarolan parçayı kaldırır ve yeni bir parçayı ekler. Bu, geri düğmesine bastığınızda değiştirilen parçanın onCreateViewçağrılmasıyla oluşturulacağı anlamına gelir . Halbuki addmevcut parçaları tutar ve mevcut parçanın aktif olacağı ve 'duraklatılmış' durumda olmayacağı anlamına gelen yeni bir parça eklerken, mevcut parça için bir geri düğmesine basıldığında onCreateView(yeni parça kullanılmadan önceki parça) katma).

Veridiliminin yaşam döngüsü olayları açısından onPause, onResume, onCreateViewve diğer yaşam döngüsü olayları söz konusu olduğunda çağrılır replaceancak halinde ileri alışkanlık add.

Edit : Bir Greenrobot Eventbus gibi bir olay otobüs kütüphanesi kullanıyor ve aynı parçayı üst üste parçası yığını için yeniden kullanıyorsa dikkatli olunmalıdır add. Bu senaryoda, en iyi uygulamaları takip edip olay otobüsü kayıt rağmen onResumeve de kaydını onPause, olay otobüsünün olarak eklenen parçanın her bir örneği aktif olacağını addya bu parça yaşam döngüsü yöntemlerinin parçası alışkanlık çağrısı. Sonuç olarak, parçanın her etkin örneğindeki olay veri yolu dinleyicisi, aynı olayı işleyebilir ve bu da istediğiniz şey olmayabilir.


1
Bir yaklaşım en üst parçası olay işlemek ve işleme tamamlandıktan sonra cancelEventDelivery () çağrı olabilir düşünüyorum. CancelEventDelivery () yöntemleri hakkında daha fazla bilgiyi burada bulabilirsiniz github.com/greenrobot/EventBus/blob/master/…
Jeevan

6
Benden +1. Mevcut parçayı yeni parçayla değiştirmenin, parça parçasından geri gelince geri almak için önceki parçanın yeniden oluşturulacağını bilmek çok önemlidir.
AndaluZ

onPause, onResume, Ana Bilgisayar Etkinliği ile sıkı sıkıya ilişkilidir. Ve parçayı değiştirirken aramadılar.
Zar E Ahmer

Sadece buna eklemek için, EventBus kullanıyorsanız, Tag ile parçayı ekleyebilir ve o etiketi etiketleyen parçadan geçirebilir ve yine de kontrol edebilirsiniz, tüm eventbus çağrılacak, sadece hangisinin çalıştırılacağını belirlersiniz
user2582318

Add () veya replace () yöntemleriyle birlikte addToBackStack () öğesini çağırdığınızı belirtmelisiniz.
rahil008

100

Bir etkinliğin 2 parçası vardır ve etkinlikteki bir düzene her parçayı FragmentManagerdeğiştirmek / eklemek için kullanırızaddToBackstack

Değiştir kullanın

Parçalara Git1

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

Parçaya Git2

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

Pop Parçası2

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

Pop Parçası1

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

Ekle'yi kullan

Parçalara Git1

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

Parçaya Git2

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

Pop Parçası2

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

Pop Parçası1

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

Örnek proje


1
değildi onPause()önce çağrılacak gerekiyordu onStop()her üzerine Pop eylem?
iCantC

addToBackStack () hakkında eksik olsa da, 'add ()' ve 'replace ()' arasında ayrım yapmak için mükemmel yanıt. Olumlu oy
Shirish Herwade

@ShirishHerwade Her iki durumda da addToBackStack ile add ve replace arasındaki farkı gösterdiğine inanıyorum.
CyberShark

38

Zaten cevaplanmış eski bir soru olmasına rağmen, belki de bu sonraki örnekler kabul edilen cevabı tamamlayabilir ve benim gibi Android'deki bazı yeni programcılar için yararlı olabilir.

Seçenek 1 - "addToBackStack ()" hiçbir zaman kullanılmaz

Durum 1A - ekleme, kaldırma ve Geri düğmesini tıklatma

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

Durum 1B - ekleme, değiştirme ve Geri düğmesini tıklatma

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

Seçenek 2 - "addToBackStack ()" her zaman kullanılır

Durum 2A - Geri düğmesini ekleme, kaldırma ve tıklama

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

Durum 2B - Geri düğmesini ekleme, değiştirme, çıkarma ve tıklama

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

Seçenek 3 - "addToBackStack ()" her zaman kullanılmaz (aşağıdaki örneklerde w / o kullanılmadığını belirtir)

Durum 3A - ekleme, kaldırma ve Geri düğmesini tıklatma

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

Durum 3B - ekleme, değiştirme, çıkarma ve Geri düğmesini tıklatma

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

1
Yeterince kapsamlı. İyi çaba!
pulp_fiction

Öyleyse, parçalarla çalışırken geri düğmesinin FragmentManager.popBackStack () işlevine benzer şekilde çalıştığını söyleyebilir miyiz?
Tenten

büyük cevap, daha iyi olamaz. Bu cevap kabul edilmelidir.
Shirish Herwade

25

Arasındaki temel fark, add()ve replace()olduğu gibi tarif edilebilir:

  • add() bazı kök öğelere basitçe bir parça eklemek için kullanılır.
  • replace() benzer şekilde davranır, ancak ilk önce önceki parçaları kaldırır ve sonra bir sonraki parçayı ekler.

Veya addToBackStack()ile birlikte kullandığımızda kesin farkı görebiliriz.add()replace() .

add()... onCreateView durumunda asla geri bastığımızda asla çağrılmaz, ancak replace()geri düğmesine bastığımızda ... her zaman oncreateView çağrılır.


1
Öyleyse add () sonuçları, bir önceki parçanın görünümü yok olmadığı için android belleği açısından daha fazla yüke neden oluyor mu?
Derekyy

@Derekyy Evet, sanırım.
Arpit J.

aradığım şey
parvez rafi

2

İlk Parçayı Eklediğimizde -> add () yöntemini kullanarak İkinci Parçayı

 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();

            }
        });

Parçada add () kullandığımızda

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

Parçada replace () kullandığımızda

replace () yöntemini kullanarak First -> Second öğesinde ilk parçaya ikinci parçaya gidecek

 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

İlk Parçayı Değiştir durumunda bu yöntem fazladan çağrılır (onPause, onStop, onDestroyView fazladan çağrılır)

E / Keshav FirstFragment: onPause

E / Keshav FirstFragment: onStop

E / Keshav FirstFragment: onDestroyView


0

FragmentManger'ın ekleme ve değiştirme işlevi şu şekilde tanımlanabilir 1. ekleme, parçayı parça arka yığınına ekleyeceği ve sağladığınız belirli çerçevede gösterileceği anlamına gelir

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

2. değiştirin, parçayı verilen karedeki başka bir parçayla değiştirdiğiniz anlamına gelir.

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

İkisi arasındaki ana yardımcı program, geri istiflediğinizde, değiştirme parçasını yenileyecek, ancak ekleme önceki parçayı yenilemeyecektir.


0

Dikkat edilmesi gereken önemli şeyler:

Değiştir ve backstack ile değiştir arasındaki fark, yalnızca değiştirdiğimizde parçanın imha edildiğinde (ondestroy () çağrılır) ve backstack ile değiştir kullanıldığında onDestroy () parçacıkları çağrılmaz (yani geri düğmesine basıldığında parça çağrılır) onun onCreateView ()) ile


0

İşte add()ve arasındaki farkı gösteren bir resimreplace()

resim açıklamasını buraya girin

Bu nedenle add()yöntem , , FragmentContainer'da önceki parçanın .

İken replace()yöntemleri tüm temizler Konteynerler önceki Parçası ve sonra FragmentContainer içinde ekleyin.

AddToBackStack nedir

addtoBackStackyöntemi add () ve replace yöntemleri ile kullanılabilir. Fragment API'sında farklı bir amaca hizmet eder.

Amaç ne?

Etkinlik API'sinin aksine Parça API'si varsayılan olarak Geri Düğmesi'nde gezinme ile birlikte gelmez . Önceki Fragment'a geri dönmek isterseniz, Fragment'ta addToBackStack () yöntemini kullanırız. İkisini de anlayalım

Dava 1:

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

resim açıklamasını buraya girin

Durum 2:

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

resim açıklamasını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.