У меня есть приложение с макетом/макетом (1 активность, 1 фрагмент ListView и 1 фрагмент детали). Когда пользователь нажимает элемент в ListView, транзакция фрагмента создает фрагмент детали на правой панели, который содержит информацию, соответствующую этому элементу. Когда показан фрагмент детали, я скрываю кнопки/элементы начальных кнопок действий и показываю 3 новых элемента AB (done/delete/cancel). Пользователь может очистить правую панель и вернуться в исходное состояние пользовательского интерфейса, нажав кнопку "Назад" или нажав один из трех элементов AB.
Проблема, с которой я сталкиваюсь, заключается в том, что когда пользователь выбирает значок дома приложения (т.е. "вверх" ), активность загружается повторно (т.е. анимация, указывающая, что действие запускается, можно рассматривать как действие бар и пользовательский интерфейс перерисовываются). Проблема возникает только при нажатии значка дома приложения. Если пользователь нажимает кнопку "Назад" или кнопку панели "Отменить/сделать/удалить", фрагмент просто удаляется с правой панели, и пользовательский интерфейс возвращается в исходное состояние без "повторной загрузки".
XML-макет для действия следующий (внутри LinearLayout; prettify скрывает эту строку):
<fragment class="*.*.*.ListFragment"
android:id="@+id/titles" android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />
<FrameLayout android:id="@+id/details" android:layout_weight="2"
android:layout_width="0px"
android:layout_height="match_parent" />
ПодробностиFragement содержит оператор actionBar.setDisplayHomeAsUpEnabled в методе onCreate:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
ActionBar actionBar = getSherlockActivity().getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
Для фрагмента ListView и фрагментов Detail в фрагментах реализованы метод onCreateOptionsMenu() и onOptionsItemSelected(). Ниже кода фрагмента детали:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.edit_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// some variable statements...
switch (item.getItemId()) {
case android.R.id.home:
//Toast.makeText(getSherlockActivity(), "Tapped home", Toast.LENGTH_SHORT).show();
onHomeSelectedListener.onHomeSelected();
return true;
case R.id.menu_edit_item_done:
editedTask.setTitle(editedTaskTitle);
onTaskEditedListener.onTaskEdited(editedTask, UPDATE_TASK, true);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
В действии хоста я реализую onHomeSelectedListner для обработки значка на домашней странице приложения (то есть "вверх" ):
public void onHomeSelected(){
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
TaskFragment taskFragment = (TaskFragment)getSupportFragmentManager().findFragmentById(R.id.details);
ft.remove(taskFragment);
ft.commit();
manager.popBackStack();
}
Слушатель активности, которому поручено обрабатывать все другие кнопки панели действий (т.е. done/delete/cancel), является onTaskEditedListener, и помимо другого кода, который обрабатывает некоторые данные, он имеет те же операции с фрагментами, которые показаны выше.
Обновить (1/24) Основываясь на обратной связи tyczj и straya, я разместил операторы журнала внутри onCreate(), onResume(), onPause() для определения различий между onHomeSelected и onTaskEdited слушателями. Я могу подтвердить, что во время события "вверх навигации" (т.е. OnHomeSelected) onPause() вызывается onCreate() и onResume(). В то время как во время вызова onTaskEdited (т.е. Кнопки возврата или завершения/удаления/отмены) ни одно из этих событий не вызывается.
Обновление (1/25) Основываясь на предположении Марка Мерфи, я прокомментировал вызов метода onHomeSelected в инструкции case case.R.id.home, чтобы посмотреть, что будет делать Activity. Мысль заключалась в том, что приложение ничего не сделало бы с тех пор, пока не будет никаких утверждений. Оказывается, это не так. Даже без вызова метода слушателя (то есть, который удаляет фрагмент), активность перезапускается и фрагмент детали удаляется из контейнера фрагментов.
Обновление (2/28) Я временно обманывал тот факт, что мое основное действие было перезапущено, отключив анимацию окна (как указано в моем собственном ответе). Однако после дальнейшего тестирования я обнаружил ошибку. Благодаря образцу кода Вольфрама Риттмейера я смог выяснить истинную причину (причины), почему моя активность была перезапущена (в макете/подробном одиночном макете) во время навигации: 1) Хотя я использовал этот "onHomeSelectedListener" для правильного удаления фрагмента из backstack, у меня все еще был некоторый остаток кода в элементе ListView onOptionsItemSelected, который создавал новое намерение начать хостинг. Вот почему нажатие на значок приложения домой возобновило действие. 2) В моей последней реализации (показано в моем собственном ответе) я избавился от onHomeSelectedListener в действии и заменил цель startActivity (т.е. код нарушения) внутри ListView onOptionsItemSelected, чтобы использовать удаление фрагмента + код popBackStack изначально в onHomeSelectedListener.