Я учусь использовать фрагменты. У меня есть три экземпляра Fragment
, которые инициализируются в верхней части класса. Я добавляю фрагмент к деятельности, как это:
Объявление и инициализация:
Fragment A = new AFragment();
Fragment B = new BFragment();
Fragment C = new CFragment();
Замена / Добавление:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, A);
ft.addToBackStack(null);
ft.commit();
Эти фрагменты работают правильно. Каждый фрагмент прикрепляется к активности и без проблем сохраняется в заднем стеке.
Итак, когда я запускаю A
, C
а затем B
, стек выглядит так:
| |
|B|
|C|
|A|
___
И когда я нажимаю кнопку «назад», B
уничтожается и C
возобновляется.
Но когда я запускаю фрагмент A
во второй раз, вместо возобновления из заднего стека, он добавляется вверху заднего стека
| |
|A|
|C|
|A|
___
Но я хочу возобновить A
и уничтожить все фрагменты поверх него (если есть). На самом деле, мне просто нравится поведение стека по умолчанию.
Как мне это сделать?
Ожидаемое: ( A
должно быть возобновлено и верхние фрагменты должны быть уничтожены)
| |
| |
| |
|A|
___
Изменить: (предложено A - C)
Это мой пробный код:
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);
}
Проблема в том, что когда я запускаю, A
а затем B
нажимаю «назад», B
удаляется и A
возобновляется. и нажатие «назад» во второй раз должно выйти из приложения. Но оно показывает пустое окно, и я должен нажать в третий раз, чтобы закрыть его.
Кроме того, когда я запускаю A
, то B
, потом C
, потом B
снова ...
Ожидаемое:
| |
| |
|B|
|A|
___
Актуально:
| |
|B|
|B|
|A|
___
Должен ли я переопределить onBackPressed()
какие-либо настройки или я что-то упустил?
OnBackstackChangedListener
чтобы вы могли гарантировать, что имеете дело с правильным фрагментом.OnBackstackChangedListener
.instanceof
:)A-B-C-B
и нажмите один раз назад, вы вернетесь назад,A
а не назадC
. Это связано с тем, чтоpopBackStackImmediate
выдается не только указанный тег, но и все вышеперечисленное. Там есть работа?Я думаю, что этот метод может решить вашу проблему:
который был первоначально размещен в этом вопросе
источник
Шаг 1. Реализуйте интерфейс с вашим классом активности
Шаг 2: Когда вы вызываете другой фрагмент, добавьте этот метод:
источник
источник
источник
Более простым решением будет изменение этой линии
ft.replace(R.id.content_frame, A);
вft.add(R.id.content_frame, A);
И внутри вашего XML-макета, пожалуйста, используйте
Clickable
означает, что на него можно нажать указательным устройством или коснуться сенсорного устройства.Focusable
означает, что он может получить фокус от устройства ввода, например клавиатуры. Устройства ввода, такие как клавиатуры, не могут решить, в какое представление отправлять свои события ввода, основываясь на самих вводах, поэтому они отправляют их в представление, которое имеет фокус.источник