Поддержка кнопки «Назад» во фрагментах Android

Я работаю над унаследованным проектом Android, в котором используются фрагменты. Основная активность имеет боковое меню, которое позволяет пользователю нажимать на список элементов, каждый из которых открывает новый фрагмент в другом файле.

Прямо сейчас нажатие кнопки «Назад» резко закрывает приложение. Я хочу, чтобы кнопка «Назад» работала так, чтобы возвращать пользователя к ранее просмотренному фрагменту, а когда пользователь находится на самом первом просмотренном фрагменте, нажатие кнопки «Назад» приведет к окну подтверждения выхода из приложения.

Я понимаю, что мне следует использовать addToBackStack(), но я не уверен, как это реализовать в моем коде.

Вот код, исходный в mainactivity, когда элемент выбран:

FragmentManager fm = getFragmentManager();
switch (position) {
case 0:
  if (fragmentManager.findFragmentById(R.id.content_frame != null) {
    Fragment currentFragment = fragmentManager.findFragmentById(R.id.content_frame);
    fm.befineTransaction().remove(currentFragment).commit();
    fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
  }
  Item0 item1Fragment = new Item0();
  fm.beginTransaction().replace(R.id.content_frame, item0Fragment).commit();
  break;

case 1 и далее идентичны, за исключением того, что ссылки на Item0/item0Fragment заменяются соответствующими значениями.

Я очень плохо знаком с фрагментами, но из того, что я вижу, код сначала определяет, есть ли у активности фрейм для фрагмента, и если да, то он удаляет текущий фрагмент и полностью очищает задний стек фрагмента. Затем он создает новый фрагмент и заменяет текущий фрагмент новым.

Вот мой код в настоящее время после некоторых изменений, и он, кажется, работает, за исключением нескольких проблем, которые я опишу после кода:

FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
switch (position) {
case 0:
  Item0 item1Fragment = new Item0();
  ft.replace(R.id.content_frame, item0Fragment).addToBackStack(null).commit();
  break;

Приведенный выше модифицированный код обеспечивает правильную навигацию, за исключением:

  1. Когда я вернусь к самому первому фрагменту, нажатие кнопки «Назад» удалит этот фрагмент и представит пустой фрагмент на экране, а следующее нажатие кнопки «Назад» закроет приложение. Желаемым поведением было бы то, что нажатие кнопки «Назад» на самом первом фрагменте вызовет кнопку подтверждения, чтобы закрыть приложение.

  2. Когда элементы в боковом меню нажаты и выбраны, я вызываю mItemList.setItemChecked(position). Как мне вызвать обновление, когда нажата кнопка «Назад», чтобы выбрать предыдущий выбор?

Кто-нибудь знает, как это сделать?

Спасибо.


person user1118764    schedule 05.03.2014    source источник
comment
Это не рекомендуется руководством по дизайну Android. Если вы используете ящик навигации, то страницы, которые вы можете посетить из ящика, рассматриваются как навигация верхнего уровня. Если внутри конкретной страницы есть какие-либо кнопки или интерактивные списки, которые переводят пользователя к подробному представлению (навигация не верхнего уровня) или что-то в этом роде, пользователь должен иметь возможность использовать кнопку «Назад», чтобы вернуться к верхнему уровню. страница уровня. Не используйте кнопку «Назад», чтобы перейти со страницы верхнего уровня на предыдущую страницу верхнего уровня. developer.android.com/design/patterns/navigation.html   -  person Mark Buikema    schedule 05.03.2014
comment
Кроме того, взгляните на этот developer.android.com/design/patterns/navigation -drawer.html   -  person Mark Buikema    schedule 05.03.2014
comment
Итак, в моем случае мой верхний уровень состоит из item1Fragment, item2Fragment и т. д. Внутри каждого фрагмента я могу перейти к подстраницам, кнопка «Назад» вернет меня с 1 подстраницы на предыдущую. Однако, как только я снова окажусь на странице верхнего уровня, куда меня должна привести кнопка «Назад»? Например, если я запускаю свое приложение, появляется страница верхнего уровня — item1Fragment. Затем я перехожу к item3Fragment, затем к подстраницам 1-3. Когда я нахожусь на подстранице 3, нажатие назад возвращает к подстранице 2, подстранице 1, а затем к элементу 3Fragment. Теперь, когда я нахожусь на странице верхнего уровня, куда меня должна привести следующая кнопка «Назад»?   -  person user1118764    schedule 05.03.2014
comment
Если я сошлюсь на Facebook в качестве примера (не уверен, что они следуют рекомендациям Android), но запуск приложения приведет меня к Ленте новостей. Если я перехожу к другим страницам верхнего уровня, таким как «Сообщения», затем «Места рядом», затем «События», нажатие назад на «События» возвращает меня прямо к Ленте новостей. Это правильное ожидаемое поведение в соответствии с рекомендациями по дизайну Android?   -  person user1118764    schedule 05.03.2014
comment
На самом деле я собирался привести приложение Facebook в качестве примера плохого дизайна. Он использует кнопку «Назад», чтобы вернуться к предыдущему экрану, независимо от того, где вы находитесь в иерархии навигации. Это сбивает пользователя с толку и дает плохой UX. Приложение Facebook полностью противоположно тому, как должны выглядеть приложения в соответствии с Руководящими принципами дизайна Android. Когда вы находитесь на странице верхнего уровня, кнопка «Назад» должна закрыть приложение. В некоторых случаях рекомендуется запросить подтверждение у пользователя. Дополнительную информацию об этом можно найти здесь: developer.android.com/design/patterns/   -  person Mark Buikema    schedule 05.03.2014
comment
Спасибо. Я действительно хотел бы иметь экран подтверждения. Фактически, в моем случае, поскольку пользователь сначала вошел бы в систему, я хотел бы иметь экран подтверждения выхода. Как мне реализовать это в коде?   -  person user1118764    schedule 05.03.2014
comment
давайте продолжим это обсуждение в чате   -  person Mark Buikema    schedule 05.03.2014


Ответы (1)


Вы проверили developer.android? Вот как они объясняют. http://developer.android.com/training/implementing-navigation/temporal.html#back-fragments

person osayilgan    schedule 05.03.2014
comment
У меня есть, но они используют getSupportFragmentManager(), который взят из android.support.v4.app.FragmentManager, а не android.app.FragmentManager, который я использую. - person user1118764; 05.03.2014
comment
@user1118764 user1118764 Внимательно прочитайте это здесь. // Работает либо с фреймворком FragmentManager, либо с // пакетом поддержки FragmentManager (getSupportFragmentManager). - person osayilgan; 05.03.2014
comment
Они объяснили это комментариями прямо над кодом. - person osayilgan; 05.03.2014
comment
тогда вы можете напрямую вызвать getFragmentManager() вместо getSupportFragmentManager()... - person pitnal; 05.03.2014
comment
Спасибо. Код в ссылке аналогичен приведенному выше модифицированному коду, который я пробовал, за исключением того, что он использует add(), а я использую replace(). Я попытался использовать add, и хотя имя фрагмента на панели действий указывает на то, что фрагмент изменился, содержимое моих фрагментов пусто. Кроме того, даже при использовании replace() после того, как я достиг самого первого фрагмента, нажатие назад очистит область содержимого, тогда как желаемое поведение на самом деле будет подтверждением выхода. Как и когда определить, что я нахожусь на самом первом фрагменте, и переопределить кнопку «Назад», чтобы отобразить подтверждение выхода? - person user1118764; 05.03.2014
comment
@user1118764 user1118764 Я уже отвечал на аналогичный вопрос в SOF. Вы можете взглянуть. stackoverflow.com/a/20053355/1080954 - person osayilgan; 05.03.2014
comment
Но помимо этого у меня есть пример проекта в моем репозитории GitHub, в нем используются фрагменты, и это обходной путь для TabActivity. Вместо использования Activity под TabActivity он работает с фрагментами. Вы можете взглянуть и дайте мне знать, если вы не понимаете какой-либо проект. Вот он ›› github.com/osayilgan/samples/tree/master/SampleApp - person osayilgan; 05.03.2014
comment
Спасибо, это было очень полезно! - person user1118764; 06.03.2014