Дилема: коли використовувати фрагменти та види діяльності:


785

Я знаю, що Activitiesпризначені для відображення одного екрана моєї програми, в той час як Fragmentsвони призначені для багаторазового використання макетів інтерфейсу користувача з логікою, вбудованою всередину них.

Донедавна я розробляв додаток, оскільки в ньому було сказано, що їх слід розробити. Я створив, Activityщоб представляти екран своєї програми та використав фрагменти для ViewPagerабо Google Maps. Я рідко створював той ListFragmentчи інший інтерфейс, який можна використовувати повторно.

Нещодавно я натрапив на проект, який містить лише 2 Activities- це один, SettingsActivityа інший - це MainActivity. Макет поля MainActivityзаповнений багатьма прихованими фрагментами повного екрану інтерфейсу, і лише один. За Activityлогікою FragmentTransitionsміж різними екранами програми багато.

Що мені сподобалось у цьому підході, це те, що програма використовує ActionBar, він залишається неушкодженим і не рухається за допомогою анімації перемикання екрана, що і відбувається при Activityперемиканні. Це дає більш вільне відчуття цим переходам на екран.

Тож я думаю, що я прошу поділитися вашим поточним способом розробки щодо цієї теми, я знаю, що це може виглядати як питання на основі думки на перший погляд, але я розглядаю це як питання дизайну та архітектури Android ... Не дуже на основі думки.

ОНОВЛЕННЯ (01.05.2014): Після цієї презентації Еріка Берка з Square , (що, маю сказати, це чудова презентація з великою кількістю корисних інструментів для розробників Android. І я жодним чином не пов’язаний з Square)

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

З мого особистого досвіду за останні кілька місяців я виявив, що найкращий спосіб побудувати мої програми - це створити групи фрагментів, які представляють потік у програмі та представити всі ці фрагменти в одному Activity. Таким чином, Activitiesу вашій заявці ви будете мати стільки ж, скільки і кількість потоків. Таким чином панель дій залишається непорушною на всіх екранах потоку, але відтворюється при зміні потоку, який має багато сенсу. Як зазначає Ерік Берк, і як я це також зрозумів, філософія використання якомога Activitiesменше можливостей не застосовується для всіх ситуацій, оскільки це створює безлад у тому, що він називає діяльністю "Бога".


2
Ознайомтеся з моєю публікацією на SO - stackoverflow.com/questions/24647078/…
Мій Бог

Відповіді:


270

Експерти скажуть вам: "Коли я побачу користувальницький інтерфейс, я буду знати, чи потрібно використовувати Activityабо Fragment". На початку це не матиме жодного сенсу, але з часом ви насправді зможете сказати, чи потрібно вам Fragmentчи ні.

Є хороша практика, яку я знайшов для мене дуже корисною. Мені це прийшло в голову, коли я намагався щось пояснити доньці.

А саме, уявіть коробку, яка представляє екран. Чи можете ви завантажити інший екран у це поле? Якщо ви використовуєте нове поле, чи доведеться копіювати кілька предметів з 1-го вікна? Якщо відповідь - так, то вам слід скористатися Fragments, оскільки корінь Activityможе вмістити всі дублювані елементи, щоб заощадити ваш час на їх створення, і ви можете просто замінити частини поля.

Але не забувайте, що вам завжди потрібен контейнер для ящика ( Activity), або ваші частини будуть розкидані. Так одна коробка з деталями всередині.

Слідкуйте за тим, щоб не зловживати коробкою. Експерти Android UX радять (ви можете їх знайти на YouTube), коли ми повинні явно завантажувати інший Activity, а не використовувати Fragment(наприклад, коли ми маємо справу з навігаційним ящиком, який містить категорії). Як тільки вам буде комфортно Fragments, ви можете переглянути всі їхні відео. Ще більше вони є обов'язковим матеріалом.

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


4
чи є у вас посилання на згаданий вами канал YouTube? Я шукаю "експертів Android UX" та "Android UX", але не зовсім впевнений, про які відео ви говорите.
я--

2
Не більше, дивилися це понад рік тому. Шукайте офіційного розробника Android, що розмовляє про UX
sandalone

1
Один з прикладів розгляду: у діяльності є parentActivity, тому ми можемо синтезувати backstack під час входу з повідомлення, але я не думаю, що існує такий parentFragment.
fikr4n


@ToolmakerSteve так, це getParentFragment, але це не те, що я мав на увазі чувак, дивіться developer.android.com/guide/topics/manifest/…
fikr4n

129

Моя філософія така:

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

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

Це лише моя філософія, оскільки фрагменти були представлені.


2
правда, але, як ви вже писали, іноді потрібно використовувати діяльність. одним із прикладів є екран камери, де краще використовувати його в альбомному режимі. інший приклад - екран конфігурації, який відображається, коли ви розміщуєте налаштований appWidget (на "робочому столі" - додаток запуску).
андроїд розробник

Дякуємо, що відповіли та поділилися своїм досвідом. Отже, ви вважаєте, що в Android є хорошою практикою обмежувати додаток однією діяльністю та використовувати Fragment для всіх екранів, якщо архітектура програми дозволяє це?
Еміль Адц

1
Тоді як ви вирішуєте питання фрагментів, які потрібно пройти в будь-який "стан"? Увесь стан у всіх ваших фрагментах повинен жити в одній діяльності, інакше ви змушені використовувати одиночку.
Mr_E

36
Я не переконаний, що спілкуватися між різними фрагментами набагато простіше, ніж надсилати дані туди і назад між видами діяльності.
Денні

3
Принаймні, onActivityResult()безпечніше і легше, ніж зворотні виклики фрагментів.
CoolMind

59

Що ж, згідно з лекціями Google (можливо, тут я не пам’ятаю), вам слід розглянути можливість використання фрагментів, коли це можливо, оскільки це полегшує ваш код і підтримує його.

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

Я думаю, ви самі повинні вирішити, що краще для вас. Перетворити діяльність у фрагмент зазвичай не так складно і навпаки.

Я створив пост про цю дилему тут , якщо ви хочете прочитати трохи далі.


5
Дякуємо, що відповіли та поділилися своїм досвідом. Отже, ви вважаєте, що в Android є хорошою практикою обмежувати додаток однією діяльністю та використовувати Fragment для всіх екранів, якщо архітектура програми дозволяє це?
Еміль Адц

Це залежить від проекту, але якщо він стає занадто складним для вас, ви також можете розділити на кілька заходів. Не бійтеся використовувати будь-який із методів. Ви також можете використовувати їх обох. Можливо, іноді вам буде важко використовувати фрагменти замість діяльності. Я думаю, ви повинні спробувати використовувати фрагменти, але не змушуйте його бути скрізь, якщо він стає занадто багато на вашому шляху ...
android developer

що робити, якщо я хочу, щоб це впливало на те, що ActionBar залишається недоторканим, і весь вміст перемикається? Чи можна цього досягти за допомогою діяльності?
Еміль Адц


27

Чому я віддаю перевагу фрагменту над активністю у ВСІХ СЛУЧАХ.

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

  • Backstackманіпуляції. З FragmentManager, це легко очистити всі фрагменти, вставити більш ніж на фрагментах і СНПЕ. Але для діяльності це буде кошмаром маніпулювати цими речами.

  • Набагато передбачуваний життєвий цикл . Поки активність хоста не переробляється. Фрагменти в рюкзаку не переробляються. Таким чином, можна використовувати FragmentManager::getFragments()для пошуку конкретного фрагмента (не рекомендується).


Здравствуйте, я читав ваш відгук про переваги Frag над Act. Чи є у вас проект, який би показав те саме у вашому Github Repo?
Ümañg ßürmån

24

Оскільки Jetpack , додаток Single-Activity є кращою архітектурою. Корисно, особливо з компонентом навігаційної архітектури .

джерело


Дякую за це!
Сімао Гарсія

1
Сьогодні я вперше прочитав про Jetpack. :) Ми створюємо додатки для однієї активності з моменту введення фрагментів. Мульти-активність набагато складніше.
Неймовірний січень

1
@TheincredibleJan Ви праві, архітектура додатків Single Activity була кращим рішенням задовго до Jetpack
Френсіс

12

На мою думку, це не дуже актуально. Ключовим фактором, який слід врахувати, є

  1. як часто ви повторно використовуєте частини інтерфейсу користувача (наприклад, меню),
  2. додаток також для планшетів?

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


Я б сказав, що основне використання фрагментів - це створення власних представлень, не вважаючи їх як власні подання. саме так і відбувається. Фрагменти, які ми спочатку показували від Google, як зручний спосіб виготовлення програм, чутливих до планшетів, тож ви можете вставити їх у різні дії, якщо хочете. спосіб приєднати код до подання, більш-менш, і наклеїти їх там, де ви хочете (без створення спеціальних представлень).
Лассі Кіннунен

11

Не забувайте, що діяльність - це блок / компонент програми, яким можна ділитися та розпочинати через Намір! Тож кожна діяльність у вашій програмі повинна вирішувати лише один вид завдань. Якщо у вас є лише одне завдання у вашій заявці, я думаю, вам потрібна лише одна діяльність та багато фрагментів, якщо це потрібно. Звичайно, ви можете повторно використовувати фрагменти в майбутній діяльності, яка вирішує інші завдання. Цей підхід буде чітким і логічним розділенням завдань. І вам не потрібно підтримувати одну активність з різними параметрами фільтра намірів для різних наборів фрагментів. Ви визначаєте завдання на етапі проектування процесу розробки на основі вимог.


У наших програмах єдиним завданням діяльності є утримання навігаційного ящика для введення різних фрагментів. :) Чому я повинен захоплюватися намірами для фрагментів? Ясно і логічно проводити статичну посилання на "глобальний" клас даних для глобальних даних і передавати деякі значення методу створення екземпляра фрагмента.
Неймовірний січень

9

Цьому є більше, ніж ви усвідомлюєте, ви повинні пам’ятати, ніж запущена діяльність не знищує явно активність виклику. Звичайно, ви можете налаштувати його таким чином, щоб користувач натискав кнопку, щоб перейти на сторінку, ви розпочали діяльність цієї сторінки та знищили поточну. Це спричиняє багато накладних витрат. Найкраще керівництво, яке я можу вам дати:

** Почніть нову діяльність лише в тому випадку, якщо є сенс, щоб основна діяльність та ця була відкрита одночасно (придумайте кілька вікон).

Чудовий приклад того, коли має сенс проводити кілька заходів - Google Drive. Основна діяльність забезпечує провідник файлів. Коли файл відкривається, для перегляду цього файлу запускається нова активність. Ви можете натиснути кнопку останніх програм, яка дозволить вам повернутися до браузера, не закриваючи відкритий документ, а потім, можливо, навіть відкрити ще один документ паралельно першому.


Повторно "Почніть нову діяльність, лише якщо має сенс мати основну діяльність та цю відкриту одночасно (придумайте кілька вікон)." Я не думаю, що так. Ця ситуація добре вирішена за допомогою фрагментів attach / detachметодів.
ToolmakerSteve

7

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

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

Моє рішення для цього - використання діяльності, щоб загортати фрагмент всередину. Отже, у нас є окремий рядок дій, меню startActivityForResult, анімація, ...


1
Дуже корисні моменти, дякую. Чи можете ви уточнити " Діяльність із загортання фрагмента "? Ви зробили окрему активність для кожного фрагмента? Якщо так, то вам взагалі потрібен фрагмент?
ToolmakerSteve

3
є спосіб відновити назву та інше. використовувати, getSupportFragmentManager().addOnBackStackChangedListenerщоб додати слухача. отримати поточний фрагмент у цього слухача, а потім встановити заголовок та інше.
бабай

4

Найбільшою перевагою fragmentнадмірної активності є те, що код, який використовується для фрагмента, може використовуватися для різних видів діяльності, тому він забезпечує повторну використання коду в розробці додатків.


3
Як? Чи можете ви надати приклад, будь ласка?
sofs1

1
@ sofs1 Ваше питання не має великого сенсу. Будь-який код у фрагменті залишається тим самим незалежно від того, з якої діяльності фрагмент встановлений.
Неймовірний січень

@TheincredibleJan Але чи не могли ми також сказати "Будь-який код у діяльності залишається тим самим незалежно від того, з якої діяльності інстанціюється друга активність."? Я не бачу різниці.
iforce2d

3

використовувати одну активність для кожної програми , щоб забезпечити основу для fragment використання fragmentна екран, fragmentsє полегшеним вагою , в порівнянні з activites фрагментами є багаторазовими фрагменти краще підходить для додатків , які підтримують як телефон & таблетку


2

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

Подумайте, як фрагменти зберігають дані про сміття. Коли ви реалізуєте фрагмент, у вас є корінь активності, який потрібно заповнити фрагментом. Отже, якщо ви намагаєтеся реалізувати безліч заходів із занадто великою кількістю фрагментів, вам доведеться врахувати ефективність програми, оскільки ви маніпулюєте (грубо говорить) двома контекстами життєвого циклу, пам’ятайте про складність.

Пам'ятайте: чи варто використовувати фрагменти? Чому я не повинен?

з повагою


1

Я використовую фрагменти для кращого користувацького досвіду. Наприклад, якщо у вас є кнопка, і ви хочете запустити, скажімо, веб-сервіс, коли ви натискаєте на нього, я додаю фрагмент до батьківської активності.

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();
}

Таким чином користувачеві не доведеться переходити до іншої діяльності.

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


Що робить цей приклад кращим для користувачів? Як вони дізнаються (або піклуються) про те, що вони роблять діяльність чи фрагмент?
iforce2d

1

Це залежить від того, що ви хочете реально побудувати. Наприклад, navigation drawerвикористовується фрагменти. Вкладки також використовуються fragments. Ще одна хороша реалізація - це те, де у вас є listview. Коли ви повертаєте телефон і клацаєте рядок, активність відображається в іншій половині екрана. Особисто я використовую fragmentsі fragment dialogs, як це більш професійно. Плюс з ними обробляється легше в обертанні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.