Дилемма: когда использовать фрагменты против действий:

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

Еще недавно я разработал приложение, в котором говорилось, что они должны быть разработаны. Я создал Activity представлять экран моего приложения и использованные фрагменты для ViewPager или же Google Maps, Я редко создавал ListFragment или другой пользовательский интерфейс, который можно использовать несколько раз.

Недавно я наткнулся на проект, который содержит только 2 Activities один это SettingsActivity а другой это MainActivity, Макет MainActivity заполнен многими скрытыми фрагментами полноэкранного интерфейса, и отображается только один. в Acitivty логики много FragmentTransitions между различными экранами приложения.

Что мне понравилось в этом подходе, так это то, что приложение использует ActionBarостается неизменным и не движется с анимацией переключения экрана, что происходит с Activity переключение. Это дает более плавное ощущение этих переходов экрана.

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

ОБНОВЛЕНИЕ (01.05.2014): После этой презентации Эрика Бёрка из Square(я должен сказать, это отличная презентация с множеством полезных инструментов для разработчиков Android. И я никак не связан с Square)

http://www.infoq.com/presentations/Android-Design/

Исходя из своего личного опыта за последние несколько месяцев, я обнаружил, что лучший способ конструировать мои приложения - это создавать группы фрагментов, которые представляют поток в приложении, и представлять все эти фрагменты в одном Activity, Так что в основном у вас будет такое же количество Activities в вашем приложении как количество потоков. Таким образом, панель действий остается неизменной на всех экранах потока, но воссоздается при изменении потока, что имеет большой смысл. Как утверждает Эрик Берк и как я понял, философия использования как можно меньшего количества Activities насколько это возможно, не применимо для всех ситуаций, потому что это создает беспорядок в том, что он называет "деятельностью Бога".

17 ответов

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

Есть хорошая практика, которая мне очень помогла. Это произошло со мной, когда я пытался что-то объяснить моей дочери.

А именно, представьте себе коробку, которая представляет экран. Можете ли вы загрузить другой экран в этом окне? Если вы используете новый ящик, придется ли вам копировать несколько предметов из 1-го ящика? Если ответ Да, то вы должны использовать Fragmentsпотому что корень Activity может содержать все дублированные элементы, чтобы сэкономить ваше время при их создании, и вы можете просто заменить части коробки.

Но не забывайте, что вам всегда нужен контейнерActivity) или ваши части будут рассеяны. Итак, одна коробка с деталями внутри.

Будьте осторожны, чтобы не использовать коробку неправильно. Эксперты по Android UX советуют (вы можете найти их на YouTube), когда мы должны явно загрузить другую Activityвместо того, чтобы использовать Fragment (например, когда мы имеем дело с навигационным ящиком, у которого есть категории). Как только вы чувствуете себя комфортно с FragmentsВы можете посмотреть все их видео. Еще больше они являются обязательным материалом.

Можете ли вы прямо сейчас взглянуть на свой пользовательский интерфейс и выяснить, если вам нужно Activity или Fragment? Вы получили новую перспективу? Я думаю, что ты сделал.

Моя философия такова:

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

Переходы активности дорогие, верно? По крайней мере, я так считаю - поскольку старое действие, которое должно быть уничтожено / приостановлено / остановлено, помещено в стек, а затем новое действие должно быть создано / запущено / возобновлено.

Это просто моя философия, так как фрагменты были введены.

Что ж, согласно лекциям Google (может быть, здесь, я не помню), вы должны рассмотреть возможность использования фрагментов, когда это возможно, так как это делает ваш код легче поддерживать и контролировать.

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

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

Я создал пост об этой дилемме здесь, если вы хотите прочитать немного дальше.

Начиная с Jetpack, приложение Single-Activity является предпочтительной архитектурой. Особенно полезно с компонентом архитектуры навигации.

источник

Почему я предпочитаю Fragment, а не Activity во ВСЕХ СЛУЧАЯХ.

  • Деятельность дорогая. Во фрагменте представления и состояния свойств разделены - всякий раз, когда фрагмент находится в backstack, его взгляды будут уничтожены. Таким образом, вы можете сложить гораздо больше фрагментов, чем активность.

  • Backstack манипуляция. С FragmentManagerлегко очистить все фрагменты, вставить больше, чем фрагменты и т. д. Но для Деятельности это будет кошмар, чтобы манипулировать этими вещами.

  • Очень предсказуемый жизненный цикл. Пока Хозяин Деятельность не переработан. Фрагменты в backstack не будут переработаны. Так что можно использовать FragmentManager::getFragments() найти конкретный фрагмент (не рекомендуется).

По моему это не очень актуально. Ключевым фактором для рассмотрения является

  1. как часто вы собираетесь повторно использовать части пользовательского интерфейса (например, меню),
  2. это приложение также для планшетов?

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

Не забывайте, что действие - это блок / компонент приложения, которым можно поделиться и запустить через Intent! Таким образом, каждое действие в вашем приложении должно решать только одну задачу. Если у вас есть только одна задача в вашем приложении, то я думаю, что вам нужно только одно действие и много фрагментов, если это необходимо. Конечно, вы можете повторно использовать фрагменты в будущих действиях, которые решают другие задачи. При таком подходе будет четкое и логичное разделение задач. И вам не нужно поддерживать одно действие с разными параметрами фильтра намерений для разных наборов фрагментов. Вы определяете задачи на этапе проектирования процесса разработки на основе требований.

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

** Начните новое действие только в том случае, если имеет смысл одновременно открывать основное и это действие (подумайте о нескольких окнах).

Отличным примером того, когда имеет смысл иметь несколько действий, является Google Drive. Основным видом деятельности является файловый менеджер. Когда файл открывается, запускается новая операция для просмотра этого файла. Вы можете нажать кнопку "Недавние приложения", которая позволит вам вернуться в браузер, не закрывая открытый документ, а затем, возможно, даже открыть другой документ параллельно первому.

Что я и сделал: используя меньше фрагментов, когда это возможно. К сожалению, это возможно почти в любом случае. Итак, я получаю много фрагментов и немного деятельности. Некоторые недостатки я понял:

  • ActionBar & Меню: когда 2 фрагмента имеют разные названия, меню, что
    будет трудно справиться. Пример: при добавлении нового фрагмента вы можете изменить заголовок панели действий, но при его извлечении из backstack нет способа восстановить старый заголовок. Вам может понадобиться Панель инструментов в каждом фрагменте для этого случая, но, поверьте мне, это потратит вас больше времени.
  • Когда нам нужно startForResult, активность имеет, но фрагмент не имеет.
  • Не имеет анимации перехода по умолчанию

Мое решение для этого заключается в использовании Activity, чтобы обернуть фрагмент внутри. Таким образом, у нас есть отдельная панель действий, меню, startActivityForResult, анимация,...

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

Использовать одно действие на приложение, чтобы обеспечить базу для fragment использование fragment для экрана, fragments облегченный вес по сравнению с activitesфрагменты многоразового использования фрагменты лучше подходят для приложений, которые поддерживают как телефон, так и планшет

Вы можете использовать один из них.
По сути, вы должны оценить, какой из них является лучшим для вашего приложения. Подумайте, как вы будете управлять бизнес-потоками и как хранить / управлять настройками данных.

Подумайте, как фрагменты хранят мусорные данные. Когда вы реализуете фрагмент, у вас есть корень активности для заполнения фрагментом (ами). Таким образом, если вы пытаетесь реализовать много действий со слишком большим количеством фрагментов, вы должны учитывать производительность своего приложения, поскольку вы управляете (грубо говоря) двумя жизненными циклами контекста, помните о сложности.

Помните: я должен использовать фрагменты? Почему я не должен?

С уважением.

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

if (id == R.id.forecast) {

    ForecastFragment forecastFragment = new ForecastFragment();
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.main_content, forecastFragment);
    ft.addToBackStack("backstack");
    forecastFragment.setArguments(b);
    ft.commit();
}

Таким образом, пользователю не нужно будет переходить в другой вид деятельности.

А во-вторых, я предпочитаю фрагменты, потому что вы можете легко обращаться с ними во время вращения.

Это зависит от того, что вы хотите построить на самом деле. Например, navigation drawer использует фрагменты. Использование вкладок fragments также. Еще одна хорошая реализация, где у вас есть listview, Когда вы поворачиваете телефон и щелкаете строку, активность отображается в оставшейся половине экрана. Лично я пользуюсь fragments а также fragment dialogs, как это более профессионально. Кроме того, они обрабатываются легче во вращении.

Некоторые неправильные идеи:

  • Всегда помещайте активность в свое приложение и обрабатывайте разные экраны с фрагментами .
  • Напишите код пользовательского интерфейса прямо в действии .
  • Управляйте перемещением между экранами (я не имею в виду вкладки, я имею в виду, например, полноэкранные представления) по фрагментам .
  • Действия можно заменить фрагментами .

Вот в чем дело!

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

Когда нужно использовать каждую из них?

  • Когда у нас есть независимый экран, на котором есть несколько разных частей пользовательского интерфейса (вкладки, расширяемые экраны, частичные экраны и т. Д.), Мы должны использовать действие с некоторыми фрагментами для реализации и обработки разных частей пользовательского интерфейса отдельно на одном экране.
  • Каждая независимая часть приложения на самом деле представляет собой компонент, который концептуально отличается от других частей, и у него должна быть независимая деятельность . Например, часть входа в систему может содержать несколько различных сценариев, таких как использование имени пользователя и пароля или использование отпечатка пальца. Каждый сценарий может быть реализован фрагментом, и все связанные с входом в систему фрагменты должны обрабатываться LoginActivity . Но, например, часть заказов в приложении не имеет концептуальной связи.с логином, поэтому он должен иметь другую активность и, конечно же, может содержать некоторые фрагменты, такие как OrdersFragment, SubmitNewOrderFragment и т. д., которыми все они должны управляться с помощью OrdersActivity.
  • Не реализуйте пользовательский интерфейс непосредственно в действии. Всегда реализуйте пользовательский интерфейс фрагментами и добавляйте эти фрагменты в действие, даже если в этом действии есть только один фрагмент. Это поможет вам получить больше кода, пригодного для повторного использования, и упростить изменение пользовательского интерфейса.
  • Никогда не используйте фрагменты для бесконечной навигации в приложении, даже если вы заставляете пользователя иметь ограниченное количество фрагментов в заднем стеке. Дело в том, что когда вы добавляете новый фрагмент в задний стек и удаляете его, он не будет удален из памяти, если только родительская активность не будет уничтожена и только невидима. Поэтому, когда вы используете задний стек диспетчера фрагментов, переходя несколько раз между фрагментами в одном и том же действии (особенно в случае, если вы создаете новый фрагмент для каждой навигации и помещаете их в задний стек), вы получите исключение OutOfMemoryException в приложении. .

Я надеюсь, что это будет полезно.

Практически всегда используют фрагменты. Если вы знаете, что приложение, которое вы создаете, останется очень маленьким, дополнительные усилия по использованию фрагментов могут не окупиться, поэтому их можно не учитывать. Для более крупных приложений вводимая сложность компенсируется гибкостью, обеспечиваемой фрагментами, что упрощает обоснование их присутствия в проекте. Некоторые люди очень противятся дополнительной сложности, связанной с фрагментами и их жизненными циклами, поэтому они никогда не используют их в своих проектах. Проблема с этим подходом заключается в том, что в Android есть несколько API-интерфейсов, которые полагаются на фрагменты, такие как ViewPager и библиотека навигации Jetpack. Если вам нужно использовать эти параметры в своем приложении, вы должны использовать фрагменты, чтобы получить их преимущества.

Отрывок из: Кристин Марсикано. «Программирование для Android: Руководство Big Nerd Ranch, 4-е издание». Apple Книги.

Этот вопрос нуждается в пересмотре, посколькуJetpack Composeдостиг стабильного уровня.

Jetpack Compose — это рекомендуемый современный набор инструментов Android для создания собственного пользовательского интерфейса.

с https://developer.android.com/jetpack/compose

Типичная архитектура компоновки реактивного ранца: одно действие, несколько составных элементов и склеивание с помощью навигации реактивного ранца. Обратите внимание, что больше нет (необходимости) фрагментов.

Пример см. в разделе Сейчас в Android .

Другие вопросы по тегам