Uczę się używać fragmentów. Mam trzy instancje, Fragment
które są inicjowane w górnej części klasy. Dodaję fragment do takiej czynności:
Deklarowanie i inicjowanie:
Fragment A = new AFragment();
Fragment B = new BFragment();
Fragment C = new CFragment();
Zastąpienie / dodanie:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, A);
ft.addToBackStack(null);
ft.commit();
Te fragmenty działają poprawnie. Każdy fragment jest dołączany do ćwiczenia i bez problemu zapisywany na tylnym stosie.
Więc kiedy uruchamiam A
, C
a potem B
, stos wygląda następująco:
| |
|B|
|C|
|A|
___
A kiedy naciskam przycisk „wstecz”, B
zostaje zniszczony i C
wznowiony.
Ale kiedy uruchamiam fragment A
po raz drugi, zamiast wznowienia z tylnego stosu, jest on dodawany na górze tylnego stosu
| |
|A|
|C|
|A|
___
Ale chcę wznowić A
i zniszczyć wszystkie fragmenty na wierzchu (jeśli takie istnieją). Właściwie podoba mi się domyślne zachowanie stosu wstecznego.
Jak to osiągnąć?
Oczekiwano: ( A
należy wznowić, a górne fragmenty zniszczyć)
| |
| |
| |
|A|
___
Edycja: (sugerowane przez A - C)
Oto mój próbny kod:
private void selectItem(int position) {
Fragment problemSearch = null, problemStatistics = null;
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
String backStateName = null;
Fragment fragmentName = null;
boolean fragmentPopped = false;
switch (position) {
case 0:
fragmentName = profile;
break;
case 1:
fragmentName = submissionStatistics;
break;
case 2:
fragmentName = solvedProblemLevel;
break;
case 3:
fragmentName = latestSubmissions;
break;
case 4:
fragmentName = CPExercise;
break;
case 5:
Bundle bundle = new Bundle();
bundle.putInt("problem_no", problemNo);
problemSearch = new ProblemWebView();
problemSearch.setArguments(bundle);
fragmentName = problemSearch;
break;
case 6:
fragmentName = rankList;
break;
case 7:
fragmentName = liveSubmissions;
break;
case 8:
Bundle bundles = new Bundle();
bundles.putInt("problem_no", problemNo);
problemStatistics = new ProblemStatistics();
problemStatistics.setArguments(bundles);
fragmentName = problemStatistics;
default:
break;
}
backStateName = fragmentName.getClass().getName();
fragmentPopped = manager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped) {
ft.replace(R.id.content_frame, fragmentName);
}
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(backStateName);
ft.commit();
// I am using drawer layout
mDrawerList.setItemChecked(position, true);
setTitle(title[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
Problem polega na tym, kiedy rozpocząć A
i potem B
, a następnie naciśnij przycisk „Wstecz”, B
zostanie usunięty i A
zostanie wznowione. a ponowne naciśnięcie „wstecz” powinno zamknąć aplikację. Ale pokazuje puste okno i muszę nacisnąć trzeci raz, aby je zamknąć.
Również, kiedy uruchomić A
, a następnie B
, potem C
, potem B
znowu ...
Spodziewany:
| |
| |
|B|
|A|
___
Rzeczywisty:
| |
|B|
|B|
|A|
___
Czy powinienem nadpisać onBackPressed()
jakiekolwiek dostosowanie, czy czegoś mi brakuje?
źródło
OnBackstackChangedListener
, abyś mógł zagwarantować, że masz do czynienia z odpowiednim fragmentem.OnBackstackChangedListener
.instanceof
:)A-B-C-B
i raz wrócisz, wrócisz do,A
a nie doC
. To dlatego, żepopBackStackImmediate
nie tylko wyskakuje podany tag, ale także wszystko powyżej. Czy jest tam jakaś praca?Myślę, że ta metoda może rozwiązać twój problem:
który został pierwotnie opublikowany w tym pytaniu
źródło
Krok 1: Zaimplementuj interfejs ze swoją klasą aktywności
Krok 2: Kiedy wywołasz inny fragment, dodaj tę metodę:
źródło
źródło
źródło
Łatwiejszym rozwiązaniem będzie zmiana tej linii
ft.replace(R.id.content_frame, A);
doft.add(R.id.content_frame, A);
Wewnątrz swojego układu XML użyj
Clickable
oznacza, że można go kliknąć za pomocą urządzenia wskazującego lub dotknąć za pomocą urządzenia dotykowego.Focusable
oznacza, że może uzyskać fokus z urządzenia wejściowego, takiego jak klawiatura. Urządzenia wejściowe, takie jak klawiatury, nie mogą zdecydować, do którego widoku wysłać zdarzenia wejściowe na podstawie samych danych wejściowych, więc wysyłają je do widoku, który ma fokus.źródło