Czynność:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment1 fragment = new Fragment1();
Fragment2 fragment2 = new Fragment2();
transaction.replace(R.id.Fragment1, fragment);
transaction.addToBackStack(null);
transaction.commit();
FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
transaction2.replace(R.id.Fragment1, fragment2);
transaction2.addToBackStack(null);
transaction2.commit();
Kod w widoku:
<fragment
android:id="@+id/Fragment1"
android:name="com.landa.fragment.Fragment1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="@+id/include1" />
Problem polega na tym, że treść tak naprawdę nie jest zastępowana - zostaje umieszczona na wierzchu (więc zachodzi na siebie).
Kiedy klikam wstecz, pierwszy fragment jest wyświetlany poprawnie (bez drugiego), ale początkowo oba są widoczne (chcę, aby był widoczny tylko ostatni).
Czego tu brakuje?
android
android-fragments
Narzędzie
źródło
źródło
containerViewId
(wreplace
metodzie).Odpowiedzi:
Robisz tutaj dwie rzeczy źle:
Nie można zastąpić fragmentu, który jest umieszczony statycznie w
xml
pliku układu. Należy utworzyć kontener (np. AFrameLayout
) w układzie, a następnie dodać fragment programowo za pomocąFragmentTransaction
.FragmentTransaction.replace
oczekuje identyfikatora kontenera zawierającego fragment, a nie identyfikatora fragmentu jako pierwszego parametru. Więc powinieneś przekazać pierwszy argument jako identyfikator kontenera, do którego dodałeś pierwszy fragment.Możesz skorzystać z tego linku, aby uzyskać więcej informacji.
źródło
FrameLayout
jako kontenera jest lepsze niż używanieLinearLayout
.addTobackStack(..)
podczas wykonywania transakcji po raz pierwszy. Pozwoli to uniknąć umieszczania pustego kontenera FrameLayout na tylnym stosie. Nadal będziesz mógł wrócić do dodawanego fragmentu.Miałem podobny problem, ale moim problemem było to, że korzystałem z dwóch różnych menedżerów fragmentów: jednego z
getSupportFragmentManager()
i jednego zgetFragmentManager()
. Gdybym dodał jeden fragment z,SupportFragmentManager
a następnie spróbował zastąpić fragment zFragmentManager
, fragment zostałby dodany na górze. Musiałem zmienić kod,FragmentManager
żeby był używany i to załatwiło sprawę.źródło
Witryna programistów Androida sugeruje użycie a
FrameLayout
do dynamicznego ładowania fragmentów w czasie wykonywania. Zakodowałeś na stałe fragment w swoim pliku xml. Dlatego nie można go usunąć w czasie wykonywania, jak wspomniano w tym linku:http://developer.android.com/training/basics/fragments/creating.html
ten link pokazuje, jak dodawać fragmenty za pośrednictwem programu:
http://developer.android.com/training/basics/fragments/fragment-ui.html
źródło
Miałem ten sam problem i widziałem wszystkie odpowiedzi, ale żadna z nich nie zawierała mojego błędu! Przed próbą zastąpienia obecnego fragmentu pokazywałem domyślny fragment w xml aktywności kontenera w następujący sposób:
po tym, chociaż przechodziłem
FrameLayout
do,fragmentTransaction.replace()
ale miałem dokładny problem. pokazywał drugi fragment na poprzednim.Problem rozwiązany poprzez usunięcie fragmentu z xml i pokazanie go programowo w
onCreate()
metodzie działania kontenera dla domyślnego podglądu na starcie programu w następujący sposób:i kontener działań xml:
źródło
Przed zastąpieniem fragmentów możesz wyczyścić BackStack:
źródło
Dodaj
android:background="?android:windowBackground">
do pojemnika, w którym znajduje się Twój fragment. W moim przypadku dodałemFrameLayout
, to powinno pomóc.źródło
Użyj kontenera zamiast fragmentu
Teraz w MainActivity
Zwróć uwagę, że Twoja klasa fragmentów powinna importować „android.app.Fragment”. Upewnij się, że używasz „support.v4” lub „oryginalnych” implementacji i nie mieszaj ich. Dostałem ten problem, ponieważ je wymieszałem.
źródło
Zgadzam się z odpowiedzią Sapana Diwakara. Ale znalazłem obejście, jak to zrobić.
Po pierwsze, w swojej aktywności (np.
activity_main
), W której masz wszystkie układy, dodaj plikFrameLayout
. Powinna mieć wysokość i szerokośćmatch parent
. Nadaj mu również plikid
.Teraz w twoim fragmencie, który ma zastąpić obecny układ, wywołaj
onPause()
ionResume()
. Zainicjuj wszystkie wewnętrzne pojemniki w formacieView
. I ustaw ichvisibility
doGONE
wewnątrzonResume()
i doVISIBLE
wewnątrzonPause()
.UWAGA : Nie ten,
FrameLayout
który zastępujesz tym fragmentem.Załóżmy, że masz
ViewPager
,TabLayout
,ImageView
a zwyczaj<fragment>
wactivity_main.xml
. Dodaj,FrameLayout
jak wspomniano powyżej.W
abcFragment.java
, wonClick()
zależności, dodaćaddToBackstack(null)
wtransaction
.Przykładowy kod:
w xyzFragment, który ma zastąpić abcFragment (i wszystko pokazane w activity_main.xml), zrób to
Miłego kodowania!
źródło
Możesz użyć metody setTransition z FragmentTransaction, aby naprawić nakładający się problem.
źródło
W Oncreate ()
teraz to będzie zawsze twój domyślny fragment ... jeśli dodasz fragment w układzie xml będzie on zawsze nakładał się, więc ustaw początkową zawartość z fragmentem w czasie wykonywania
źródło
miałem ten sam problem po rozwiązaniu tego problemu
Weź układ ramek, w którym zastępujesz fragment ur
i kod do wymiany
jeśli chcesz cały przykład, wyślę ci tylko komentarz ......
źródło
Miałem też ten sam problem, ale to dlatego, że nie zmieniłem koloru tła fragmentu, który próbowałem dodać do mojego framelayout.
Spróbuj to zrobić za pomocą
layout_height
ilayout_width
ustaw namatch_parent
źródło
Kiedyś miałem ten problem i dowiedziałem się, że to dlatego, że przypadkowo usunąłem
android:background
atrybut, którego brakuje w twoim kodzie xml. Uważam, że to działa tak, jak podczas malowania ściany,android:background
jest to kolor, który będzie miała ściana, a inne widoki są umieszczane na tym kolorze podstawowym. Jeśli nie pomalujesz ściany przed umieszczeniem widoków, będą one nad tym, co już było w tej ścianie, w twoim przypadku na drugim fragmencie. Nie wiem, czy to ci pomoże, powodzenia.źródło
Przede wszystkim próbowałem i próbowałem rozwiązać problem, ale nadal nie mam rozwiązania. Nie wiem, dlaczego to nie działa dla mnie. Zgadzam się z powyższymi odpowiedziami, ponieważ tak wielu się z nimi zgadza.
Po prostu przedłużam odpowiedź, a poniżej jest sposób, który działa dla mnie.
Mam nadzieję, że ktoś otrzyma pomoc.
źródło
Dziękuję Sapanowi Diwakarowi i innym. Ta odpowiedź mi pomogła. Po prostu utworzyłem RelativeLayout bez fragmentu w środku, użyłem RelativeLayout jako widoku nadrzędnego lub grupy, określiłem ten widok grupy w transakcji do zastąpienia i zadziałało.
Kod:
XML:
źródło
Sprawdź identyfikator układu ramki i wymień go jak poniżej
źródło