Android: правильный способ перехода между фрагментами

Это вопрос дизайна, а не технического.

Общий случай: я хочу, чтобы событие пользовательского интерфейса во фрагменте вносило изменения во всю активность.

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

Однако я не хочу, чтобы мои Фрагменты касались моей деятельности. Возможно, я захочу изменить поведение позже (возможно, на большом экране покажу оба фрагмента вместо замены первого), и я не хочу, чтобы мой код фрагмента имел такую ​​логику.

Что я сделал, так это реализовал класс Listener в своих фрагментах, который сообщает о событиях обратно в Activity. Таким образом, если я хочу использовать другой класс Activity с другим поведением отображения, я могу просто изменить прослушиватель и оставить код Fragment нетронутым.

Это хороший способ сделать это? Существует ли стандартная передовая практика или лучший шаблон проектирования?


person slezica    schedule 06.09.2011    source источник


Ответы (3)


Использование прослушивателей — рекомендуемый способ связи между Fragment и вашей активностью.

Дополнительную информацию см. в этом разделе документации по Android. Короче говоря, они просто реализуют интерфейс слушателя с помощью класса Activity и передают результат getActivity() в виде фрагмента слушателю.

По моему личному опыту это очень удобно, т.к. позволяет:

  1. Простое переключение базовой активности (например, вы размещаете весь фрагмент в активности-оболочке для совместимости в версиях до 3.0 и размещаете этот фрагмент вместе с другими в 11+).
  2. Легко контролировать, поддерживает ли действие-оболочка обратные вызовы или нет. Просто проверьте, реализует ли он прослушиватель, и выполните определенные действия вашего приложения, если это не так.
person EvilDuck    schedule 14.09.2011

Вы правы в использовании Listener. Это то, с чем мне также приходилось иметь дело в проекте на работе. Лучший способ справиться с этим — сделать Фрагмент автономным по своей природе. Все, кто хочет взаимодействовать с фрагментом, должны использовать его общедоступный API и/или устанавливать прослушиватели для определенных событий. Если вы знакомы с шаблонами проектирования, это Шаблон Observer. События могут быть общими или специфическими, а также содержать данные или не содержать данных.

В качестве примера моего проекта у меня было два Фрагмента. ListFragment и InfoFragment, отображающие выбранный ListItem. У ListFragment уже есть интерфейс Listener для подключения к моей Activity, но у InfoFragment нет, так как это ваш базовый фрагмент. Я добавил к InfoFragment интерфейс прослушивателя, который будет уведомлен, когда фрагмент захочет закрыться. Для фрагмента это может быть нажатие кнопки или определенное действие, но что касается моей активности, когда событие запускается, оно закрывает представление фрагмента.

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

person Spidy    schedule 09.09.2011
comment
У меня похожая проблема. У меня есть FragmentActivity, которая управляет фрагментами списка tabhost 4, и каждый ListFragment может, в зависимости от взаимодействия с пользователем, запускать другие фрагменты (все фрагменты используют один и тот же макет, где отображается их содержимое). Является ли все еще действительным шаблон обратного вызова? Благодарность - person Blackbelt; 25.09.2011
comment
Да, шаблон обратного вызова идеально подходит для этого. Пусть Activity сделает этот запуск, прослушав все фрагменты - person Spidy; 26.09.2011

Технический ответ на:

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

    FragmentTransaction ft = this.getFragmentManager().beginTransaction();
    Fragment mFragment = Fragment.instantiate(this.Activity(), Fragment2.class.getName());
    ft.replace(android.R.id.content, mFragment);
    ft.commit();
person Guilherme Torres Castro    schedule 10.12.2012