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


485

В Android API 11+ Google выпустил новый класс под названием Fragment.

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

Какова цель фрагментов и их возможное использование (кроме некоторых примеров пользовательского интерфейса, которые могут быть легко достигнуты с помощью простых представлений / макетов)?

Мой вопрос о фрагментах:

  1. Каковы цели использования фрагмента?
  2. Каковы преимущества и недостатки использования фрагментов по сравнению с использованием действий / представлений / макетов?

Бонусные вопросы:

  1. Можете ли вы дать некоторые действительно интересные использования для фрагментов? Вещи, которые Google не упомянул в своих видео?
  2. Как лучше всего общаться между фрагментами и действиями, которые их содержат?
  3. Что нужно помнить при использовании фрагментов? Какие-нибудь советы и предупреждения из вашего опыта?


Ответы:


282

# 1 и # 2 каковы цели использования фрагмента и каковы преимущества и недостатки использования фрагментов по сравнению с использованием действий / представлений / макетов?

Фрагменты - это решение Android для создания пользовательских интерфейсов многократного использования. Вы можете достичь некоторых из тех же результатов, используя действия и макеты (например, используя include). Однако; фрагменты подключены к Android API, от HoneyComb и выше. Позвольте мне уточнить;

  • ActionBar. Если вам нужны вкладки для навигации по вашему приложению, вы быстро увидите, что ActionBar.TabListenerинтерфейс дает вам FragmentTransactionвходной аргумент для onTabSelectedметода. Возможно, вы могли бы игнорировать это, и делать что-то еще и умнее, но вы будете работать против API, а не с этим.

  • FragmentManagerРучками «назад» для вас в очень умным способом. Вернуться не означает вернуться к последнему занятию, как к обычным занятиям. Это значит вернуться к предыдущему состоянию фрагмента.

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

  • Ваша жизнь станет намного проще, если вы будете использовать Фрагменты, когда будете пытаться создавать приложения для телефонов и планшетов. Поскольку фрагменты тесно связаны с API-интерфейсами Honeycomb +, вы захотите использовать их и на телефонах для повторного использования кода. Вот где библиотека совместимости пригодится.

  • Вы даже можете и должны использовать фрагменты для приложений, предназначенных только для телефонов. Если вы думаете о переносимости. Я использую ActionBarSherlockбиблиотеки совместимости для создания «ICS-выглядящих» приложений, которые выглядят одинаково вплоть до версии 1.6. Вы получаете новейшие функции, такие как ActionBar: вкладки, переполнение, панель разделенных действий, панель просмотра и т. Д.

Бонус 2

Лучший способ общения между фрагментами - это намерения. Когда вы нажимаете что-то во фрагменте, вы обычно звоните StartActivity()с данными на нем. Намерение передается всем фрагментам действия, которое вы запускаете.


5
Прежде всего, спасибо. Я ценю людей, которые дают информативные (но короткие) ответы, а не просто дают мне ссылку на руководство. Кроме того, помимо дополнительных функций для работы со специальными классами, вы можете подумать о преимуществах и недостатках работы с фрагментами ?
Android-разработчик

4
Я думаю, что вы должны быть более прямыми в своих вопросах. Я только что дал четыре основных преимущества выше.
Гленн Бек

2
хорошо, что относительно недостатков по сравнению с настроенными представлениями и действиями?
Android-разработчик

2
как вы общаетесь между фрагментами, используя намерения? все ли фрагменты должны быть «живыми» (добавленными в упражнение), чтобы они могли общаться друг с другом?
Android-разработчик

55
Один фрагмент никогда не должен общаться напрямую с другим фрагментом - вместо этого выполните родительскую активность. Таким образом, вы не получите спагетти-код, а сможете легко управлять кодом.
slott

70

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

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


1
обновленный вопрос. теперь он имеет ссылки на видео Google. также, спасибо за объяснение, но мне все еще нужно разъяснение по моему вопросу.
Android-разработчик

5
Прочитайте запись руководства разработчика, в ней более чем достаточно подробностей. Маловероятно, что вы получите ответ на «крутое использование фрагментов» на SO - путь расплывчатый, и единого ответа не существует. Ответ на номер 4 конкретно дан в руководстве разработчика
Николай Еленков

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

3
Спасибо разработчику Android за настойчивые ответы на основной вопрос. ATM Я не видел ничего полезного для меня в классе Fragment с использованием XML-тега «include». Ценами, которые я считаю ценными, будет возможность указать один макет, который волшебным образом превратится в лучший пользовательский интерфейс при любом разрешении. Из того, что я могу сказать, вам все еще нужно сделать это в коде самостоятельно. Другим потенциальным значением может быть способ объединения кода + ресурсов в повторно используемые компоненты, которых нет в приложениях для повторного использования, но опять-таки их там нет. Я хочу одну действительно вескую причину.
Мелинда Грин

2
Я начинаю понимать, как Google предлагает использовать фрагменты, но я вполне согласен с @NikolayElenkov .. Мне кажется, что использование Activity по-прежнему является наиболее надежным и менее сложным способом ...
andrea.rinaldi

49

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

Ниже приведены важные моменты о фрагменте:

  1. Фрагмент имеет свою собственную разметку и свое собственное поведение со своими собственными обратными вызовами жизненного цикла.

  2. Вы можете добавлять или удалять фрагменты в действии во время его выполнения.

  3. Вы можете объединить несколько фрагментов в одном действии для создания многопанельного пользовательского интерфейса.

  4. Фрагмент может быть использован в нескольких видах деятельности.

  5. Жизненный цикл фрагмента тесно связан с жизненным циклом активности хоста.

  6. Когда действие приостановлено, все фрагменты, доступные в активности, также будут остановлены.

  7. Фрагмент может реализовать поведение, которое не имеет компонента пользовательского интерфейса.

  8. Фрагменты были добавлены в Android API в Android 3 (Honeycomb) с API версии 11.

Для более подробной информации, пожалуйста, посетите официальный сайт, Фрагменты .


1. Как вы упомянули на # 8, он не должен иметь макет. 6. Вы пропустили часть после «значит». В любом случае, спасибо за помощь другим, чтобы сделать это понятнее. Я дам тебе +1.
Android-разработчик

1
Что касается # 8, возможный пример фрагмента без макета (то есть фрагмента без заголовка) будет таким, который выполняет задачу, которая, несмотря на то, что является несколько короткой (такой как короткий запрос HTTP), все еще требуется для того, чтобы пережить изменения конфигурации и, таким образом, зависит на точном экземпляре фрагмента, сохраненном через них (используя setRetainInstance (true) на фрагменте). Что касается фрагментов макета, setRetainInstance (true) не имеет особого смысла, так как предотвращает освобождение ресурсов, связанных с их представлениями, когда это необходимо (т. Е. Утечка памяти).
Пиовезан

ПРИМЕЧАНИЕ: «# 8» теперь «# 7».
ToolmakerSteve

21

Это важная информация, которую я нашел на фрагментах:

Исторически каждый экран в приложении Android был реализован как отдельное действие. Это создает проблему при передаче информации между экранами, поскольку механизм Намерения Android не позволяет передавать ссылочный тип (то есть объект) непосредственно между операциями. Вместо этого объект должен быть сериализован или должна быть доступна глобально доступная ссылка.

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

Источник: https://www.pluralsight.com/blog/software-development/android-fragments


3
Это правда, но есть решения для этого: используйте Parcelable, когда это не большой объект (и есть плагин, чтобы облегчить его), и если это огромный объект, вы всегда можете использовать статическую ссылку, которая будет иметь значение null когда вы доберетесь до новой деятельности (или когда вы ее уничтожите, в зависимости от ваших требований).
Android-разработчик

@androiddeveloper: «use Parcelable» соответствует моему определению «головной боли при передаче данных, которую можно избежать с помощью фрагментов». Если существует сложное общее состояние, которое должно сохраняться, пока проходит ряд экранов, то «Деятельность + Фрагменты» является хорошим решением, ИМХО. (Хотя я отказался от заднего стека фрагментов и сам управлял тем, что означает «назад».)
ToolmakerSteve

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

10

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

Пример:

Деятельность A, Деятельность B, Деятельность C:

  • Все действия должны повторяться в одном и том же коде, например, для отображения базовой панели инструментов, или наследоваться от родительского действия (управление становится громоздким).
  • Чтобы перейти от одного действия к другому, либо все они должны находиться в памяти (накладные расходы), либо одно должно быть уничтожено, чтобы открылось другое.
  • Связь между действиями может быть сделана через Intents.

против

Деятельность А, Фрагмент 1, Фрагмент 2, Фрагмент 3:

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

идеальный ответ!
суббота

8

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

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

Я новичок в Android и до сих пор думаю, что фрагмент полезен таким образом.


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

@androiddeveloper Вы просто используете мероприятия в основном?
Майкл Алан Хафф

@MichaelAlanHuff При поддержке планшетов, я думаю, лучше использовать фрагменты. Кроме того, при поддержке изменений ориентации и других подобных событий вы можете использовать DialogFragment, так как он позволяет вам их восстанавливать
android developer

@androiddeveloper, я тоже так думаю. Я не использовал DialogFragments так часто. Чтобы помочь модульности логики, многие разработчики андроидов начинают использовать собственные представления, чтобы держать логику в минусе. Вот недавний разговор о пользовательских взглядах, предоставленных инженером из Airbnb vimeo.com/127799187
Майкл Алан Хафф

@MichaelAlanHuff использование фрагментов также может быть полезно, если вы считаете, что текущий экран может быть частью другого экрана.
Android-разработчик

5

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

  • Фрагменты могут использоваться для заполнения Menus и могут обрабатывать MenuItemклики самостоятельно. Таким образом, давая дополнительные возможности модуляции для вашей деятельности. Вы можете выполнять работу с ContextualActionBar и т. Д., Не подозревая об этом свою деятельность и, в принципе, можно отделить ее от основной вещи, которую обрабатывает ваша деятельность (Навигация / Настройки / О программе).

  • Родительский Frag с дочерними Frags может дать вам дополнительные возможности для модуляции ваших компонентов. Например, вы можете легко менять местами фраги, помещать новые фраги в пейджер или удалять их, переставлять их. Все без вашей Деятельности, ничего не зная об этом, просто сосредоточившись на вещах более высокого уровня.


0

Фрагменты живут в Деятельности и имеют:

  • свой жизненный цикл
  • свой макет
  • свои дочерние фрагменты и пр.

Думайте о Фрагментах как о подгруппе основной деятельности, к которой он принадлежит, он не может существовать сам по себе и его можно вызывать / использовать снова и снова. Надеюсь это поможет :)


На самом деле, что касается второго пункта («его собственный макет»), это необязательно. Фрагмент не должен иметь вид вообще.
Android-разработчик

0

1. Цели использования фрагмента?

  • Ans:
    1. Обработка различий в форм-факторе устройства.
    2. Передача информации между экранами приложений.
    3. Организация пользовательского интерфейса.
    4. Расширенные метафоры пользовательского интерфейса.

0

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


6
"на себя"? Возможно, "самостоятельно"? Или "само собой"?
Питер Мортенсен
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.