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

<p>я знаю, что <code>activities</code> предназначены для представления одного экрана моего приложения, в то время как <code>fragments</code> предназначены для многократного использования макетов пользовательского интерфейса со встроенной в них логикой.</p><p>еще недавно я разработал приложение, в котором говорилось, что они должны быть разработаны. я создал <code>activity</code> для представления экрана моего приложения и использовал фрагменты для <code>viewpager</code> или <code>google maps</code>. я редко создавал <code>listfragment</code> или другой пользовательский интерфейс, который можно использовать несколько раз.</p><p>недавно я наткнулся на проект, который содержит только 2 <code>activities</code> один <code>settingsactivity</code> и другой <code>mainactivity</code>. макет <code>mainactivity</code> заполнен множеством скрытых фрагментов полноэкранного пользовательского интерфейса, и отображается только один. в логике <code>activity</code> есть много <code>fragmenttransitions</code> между различными экранами приложения.</p><p>что мне понравилось в этом подходе, так это то, что, поскольку приложение использует <code>actionbar</code>, оно остается неизменным и не перемещается с анимацией переключения экрана, что происходит при переключении <code>activity</code>. это дает более плавное ощущение этих переходов экрана.</p><p>итак, я думаю, что я прошу поделиться вашей текущей манерой разработки по этой теме, я знаю, что на первый взгляд это может выглядеть как вопрос, основанный на мнении, но я рассматриваю его как android вопрос дизайна и архитектуры ... не совсем основанный на мнении.</p><p><strong> обновление (01.05.2014): </strong> после этой презентации <strong> эрик берк </strong> из <strong> square </strong>, (что я должен сказать, это отличная презентация с множеством полезных инструментов для android разработчиков. и я не никак не связаны с площадью)</p><p> <a href="http://www.infoq.com/presentations/android-design/">http://www.infoq.com/presentations/android-design/</a> </p><p>исходя из своего личного опыта за последние несколько месяцев, я обнаружил, что лучший способ создания моих приложений - это создание групп фрагментов, которые представляют <strong> поток </strong> в приложении и представить все эти фрагменты в одном <code>activity</code>. таким образом, в основном у вас будет то же число <code>activities</code> в вашем приложении, что и количество потоков. таким образом, панель действий остается неизменной на всех экранах потока, но воссоздается при изменении потока, что имеет большой смысл. как утверждает эрик берк, и, как я уже понял, философия использования как можно меньшего числа <code>activities</code> не применима для всех ситуаций, потому что она создает беспорядок в том, что он называет деятельностью "бога".</p>

<p>эксперты скажут вам: "когда я увижу пользовательский интерфейс, я буду знать, использовать ли <code>activity</code> или <code>fragment</code>". в начале это не будет иметь никакого смысла, но со временем вы сможете определить, нужно ли вам <code>fragment</code> или нет.</p><p>есть хорошая практика, которая мне очень помогла. это произошло со мной, когда я пытался что-то объяснить моей дочери.</p><p>а именно, представьте себе коробку, которая представляет экран. можете ли вы загрузить другой экран в этом окне? если вы используете новый ящик, придется ли вам копировать несколько предметов из 1-го ящика? если ответ "да", то вам следует использовать <code>fragments</code>, поскольку корневой <code>activity</code> может содержать все дублированные элементы, чтобы сэкономить ваше время на их создание, и вы можете просто заменить части блока.</p><p>но <strong>не забывайте</strong> что вам всегда нужен контейнер коробки (<code>activity</code>), иначе ваши детали будут рассеяны. итак, одна коробка с деталями внутри.</p><p>будьте осторожны, чтобы не использовать коробку не по назначению. android эксперты по ux советуют (вы можете найти их на youtube), когда нам следует явно загрузить другое <code>activity</code> вместо того, чтобы использовать <code>fragment</code> (например, когда мы имеем дело с навигационным ящиком, у которого есть категории). как только вы почувствуете себя комфортно с <code>fragments</code>, вы можете посмотреть все их видео. еще больше они являются обязательным материалом.</p><p>можете ли вы прямо сейчас взглянуть на свой пользовательский интерфейс и выяснить, нужны ли вам <code>activity</code> или <code>fragment</code>? вы получили новую перспективу? я думаю, что ты сделал.</p>

<p>моя философия такова:</p><p>создайте мероприятие, только если оно абсолютно необходимо. с задним стеком, доступным для фиксации множества транзакций фрагментов, я пытаюсь создать как можно меньше действий в своем приложении. кроме того, общение между различными фрагментами намного проще, чем отправка данных между действиями.</p><p>переходы активности дорогие, верно? по крайней мере, я так считаю - поскольку старое действие должно быть уничтожено/приостановлено/остановлено, помещено в стек, а затем новое действие должно быть создано/запущено/возобновлено.</p><p>это просто моя философия, так как фрагменты были введены.</p>

<p>ну, в соответствии с лекциями google (возможно <a href="http://www.youtube.com/watch?v=amzm8ozbgfk"><strong> здесь </strong></a> , я не помню), вы должны рассмотреть возможность использования фрагментов, когда это возможно , так как это делает ваш код легче поддерживать и контролировать.</p><p>тем не менее, я думаю, что в некоторых случаях это может стать слишком сложным, поскольку действия, в которых размещаются фрагменты, должны перемещаться между ними.</p><p>я думаю, вы должны решить сами, что лучше для вас. обычно не так сложно преобразовать действие во фрагмент и наоборот.</p><p>я создал пост об этой дилемме <a href="https://stackoverflow.com/questions/10478233/android-need-some-clarifications-of-fragments-vs-activities-and-views"><strong> здесь </strong></a> , если вы хотите почитать дальше.</p>

<p>почему я предпочитаю fragment, а не activity во всех случаях.</p><ul> <li> <p>деятельность дорогая. в fragment представления и состояния свойств разделены - всякий раз, когда фрагмент находится в <code>backstack</code>, его представления будут уничтожены. таким образом, вы можете сложить гораздо больше фрагментов, чем активность.</p> </li> <li> <p><code>backstack</code> манипуляция. с <code>fragmentmanager</code> легко очистить все фрагменты, вставить больше, чем фрагменты и т.д. но для деятельности это будет кошмар, чтобы манипулировать этими вещами.</p> </li> <li> <p>очень предсказуемый <em>жизненный цикл</em>. до тех пор, пока активность хоста не утилизируется. фрагменты в backstack не будут переработаны. таким образом, можно использовать <code>fragmentmanager::getfragments()</code>, чтобы найти конкретный фрагмент (не рекомендуется).</p> </li> </ul>

<p>по моему это не очень актуально. ключевым фактором для рассмотрения является</p><ol> <li>как часто вы собираетесь повторно использовать части пользовательского интерфейса (например, меню),</li> <li>это приложение также для планшетов?</li> </ol><p>основное использование фрагментов - создание многопользовательских операций, что делает его идеальным для приложений, работающих с планшетами и телефонами.</p>

<p>поскольку <a href="https://developer.android.com/jetpack/">jetpack</a> , <strong> приложение single-activity </strong> является предпочтительной архитектурой. особенно полезно с <a href="https://developer.android.com/topic/libraries/architecture/navigation/">компонент архитектуры навигации</a> .</p><p> <a href="http://android-developers.googleblog.com/2018/05/use-android-jetpack-to-accelerate-your.html">источник</a> </p>

<p>не забывайте, что действие - это блок/компонент приложения, которым можно поделиться и запустить через intent! таким образом, каждое действие в вашем приложении должно решать только один вид задач. если у вас есть только одна задача в вашем приложении, я думаю, что вам нужно только одно действие и много фрагментов, если это необходимо. конечно, вы можете повторно использовать фрагменты в будущих действиях, которые решают другие задачи. при таком подходе будет четкое и логичное разделение задач. и вам не нужно поддерживать одно действие с разными параметрами фильтра намерений для разных наборов фрагментов. вы определяете задачи на этапе проектирования процесса разработки на основе требований.</p>

<p>в этом есть нечто большее, чем вы думаете, вы должны помнить, что запущенное действие не влечет за собой уничтожение вызывающего действия. конечно, вы можете настроить его так, чтобы ваш пользователь нажимал кнопку, чтобы перейти на страницу, вы запускали активность этой страницы и уничтожали текущую. это вызывает много накладных расходов. лучшее руководство, которое я могу вам дать:</p><p>** начните новое действие только в том случае, если имеет смысл одновременно открывать основное и это действие (подумайте о нескольких окнах).</p><p>отличным примером того, когда имеет смысл заниматься несколькими видами деятельности, является google drive. основным видом деятельности предоставляет файловый проводник. когда файл открывается, запускается новая операция для просмотра этого файла. вы можете нажать кнопку недавних приложений, которая позволит вам вернуться в браузер, не закрывая открытый документ, а затем, возможно, даже открыть другой документ параллельно первому.</p>

<p>что я и сделал: используя меньше фрагментов, когда это возможно. к сожалению, это возможно почти в любом случае. итак, я получаю много фрагментов и немного деятельности. некоторые недостатки я понял:</p><ul> <li><code>actionbar</code> & menu: когда 2 фрагмента имеют разные названия, меню, что<br> будет трудно справиться. пример: при добавлении нового фрагмента вы можете изменить заголовок панели действий, но при извлечении его из <code>backstack</code> невозможно восстановить старый заголовок. вам может понадобиться панель инструментов в каждом фрагменте для этого случая, но, поверьте мне, это потратит вас больше времени.</li> <li>когда нам нужно <code>startforresult</code>, активность имеет, а фрагмент - нет.</li> <li>не имеет анимации перехода по умолчанию</li> </ul><p>мое решение для этого - использовать activity, чтобы <em>обернуть</em> фрагмент внутри. таким образом, у нас есть отдельная панель действий, меню, <code>startactivityforresult</code>, анимация, ...</p>

<p>одно большое преимущество <code>fragment</code> перед действием состоит в том, что код, который используется для фрагмента, может использоваться для различных действий. таким образом, он обеспечивает <em>повторное использование</em> кода при разработке приложения.</p>

<p>вы можете использовать один из них.<br> по сути, вы должны оценить, какой из них является лучшим для вашего приложения. подумайте, как вы будете управлять бизнес-потоком и как хранить/управлять настройками данных.</p><p>подумайте, как фрагменты хранят данные мусора. когда вы реализуете фрагмент, у вас есть корень активности для заполнения фрагментом (ами). таким образом, если вы пытаетесь реализовать много действий со слишком большим количеством фрагментов, вы должны учитывать производительность своего приложения, поскольку вы управляете (грубо говоря) двумя жизненными циклами контекста, помните о сложности.</p><p>помните: я должен использовать фрагменты? почему я не должен?</p><p>с уважением.</p>

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

<p>я использую фрагменты для лучшего пользовательского опыта. например, если у вас есть кнопка и вы хотите запустить, скажем, веб-сервис, когда вы нажимаете на него, я присоединяю фрагмент к родительскому действию.</p><pre><code>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(); } </code></pre><p>таким образом, пользователю не нужно будет переходить в другой вид деятельности.</p><p>а во-вторых, я предпочитаю фрагменты, потому что вы можете легко обращаться с ними во время вращения.</p>

<p>это зависит от того, что вы хотите построить на самом деле. например, <code>navigation drawer</code> использует фрагменты. вкладки также используют <code>fragments</code>. еще одна хорошая реализация, где у вас есть <code>listview</code>. когда вы поворачиваете телефон и щелкаете строку, активность отображается на оставшейся половине экрана. лично я использую <code>fragments</code> и <code>fragment dialogs</code>, так как он более профессиональный. кроме того, они обрабатываются легче во вращении.</p>