Жизненный цикл fragment android

Жизненный цикл фрагментов

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

Список дополнительных методов жизненного цикла фрагментов, которых нет у активности:

onAttach(Activity) Вызывается, когда фрагмент связывается с активностью. С этого момента мы можем получить ссылку на активность через метод getActivity() onCreate() В этом методе можно сделать работу, не связанную с интерфейсом. Например, подготовить адаптер. onCreateView(LayoutInflater, ViewGroup, Bundle) Вызывается для создания компонентов внутри фрагмента onViewCreated() Вызывается сразу после onCreateView() onActivityCreated(Bundle) Вызывается, когда отработает метод активности onCreate(), а значит фрагмент может обратиться к компонентам активности onStart() Вызывается, когда фрагмент видим для пользователя и сразу же срабатывает onStart() активности onDestroyView() onResume() Вызываем после onResume() активности Вызывается, когда набор компонентов удаляется из фрагмента onDetach() Вызывается, когда фрагмент отвязывается от активности

Одноимённые с методами активности методы фрагментов выполняют аналогичные функции. К примеру, метод onResume() вызывается, когда фрагмент вновь становится видимым.

Метод onStart() вызывается, когда фрагмент становится видимым после запуска такого же метода в родительской активности.

Фрагмент всегда связан с активностью. Отдельно фрагмент от активности существовать не может.

Если активность останавливается, то её фрагменты также останавливаются. Если активность уничтожается, то её фрагменты также уничтожаются.

Метод onCreateView() вызывается один раз, когда фрагмент должен загрузить на экран свой интерфейс. В этом методе вы можете «надуть» (inflate) разметку фрагмента через метод inflate() объекта Inflater, который задан в параметре метода. В фрагментах без интерфейса вы можете пропустить надувание.

Метод onActivityCreated() вызывается после метода onCreateView(), когда создаётся активность-хозяйка для фрагмента. Здесь можно объявить объекты, необходимые для Context.

Фрагменты не являются подклассами Context, вам следует использовать метод getActivity(), чтобы получить родительскую активность.

Создадим несколько фрагментов и с помощью логов посмотрим на срабатывание методов. Первоначально пример писался на Java, будет приведён аналог на Kotlin только для первого фрагмента, остальное придётся написать самостоятельно.

FirstFragment

Разметка для первого фрагмента

По аналогии создайте второй фрагмент SecondFragment, заменив тексты и названия идентификаторов там, где это нужно.

Создадим разметку для главной активности с двумя кнопками для переключения между фрагментами.

activity_main.xml

MainActivity.java

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

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

onAttach
onCreate
onCreateView
onActivityCreated
onStart
onResume

Метод onActivityCreated() теперь считается устаревшим.

Нажимаем на кнопку «Home»:

Запустим из списка недавно запущенных программ:

Выходим из программы через кнопку «Back»:

onPause
onStop
onDestroyView
onDestroy
onDetach

При замещении первого фрагмента вторым почти как при закрытии, только нет методов onDestroy и onDetach, а затем повторяются те же методы при старте фрагмента:

// Первый фрагмент onPause
onStop
onDestroyView
// Второй фрагмент onAttach
onCreate
onCreateView
onActivityCreated
onStart
onResume

Дополнительное чтение

xxv/android-lifecycle — схема жизненного цикла в SVG, PDF, PNG.

Источник

Fragment (Фрагменты)

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

Зачем?

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

Старые программы прекрасно на них запускались, но обнаружилось несколько недостатков. На больших экранах интерфейс выглядел не слишком элегантно, появились большие пустые пространства. И тогда возникла идея объединить два отдельных экрана из смартфона в один экран на планшете. Это самый классический пример применения фрагмента. По сути, это костыль. Возможно, если бы сразу подумали головой, то придумали бы более элегантное решение. Но теперь поздно пить «Боржоми», будем использовать предложенную концепцию.

Читайте также:  Смертельная гонка для андроид

Фрагменты были представлены в API 11 (Android 3.0), но в целях совместимости была написана специальная библиотека Android Support library для старых устройств. Долгое время существовало два класса Fragment: для новых устройств и для старых устройств. Названия методов и классов были очень похожи, и разработчики часто путались, смешивая в одном проекте два разных несовместимых класса. Спустя некоторое время решили отказаться от странного разделения, класс для новых устройств признали устаревшим, а класс из библиотеки поддержки старых устройств сменил своё полное имя и вошёл в состав AndroidX.

При желании можно было продолжить писать приложения в старом стиле, отслеживая размеры экрана. Но такой код получится слишком сложным. Пришлось бы писать один код для переключения от одной активности к другой при использовании смартфона и другой код, когда взаимодействие между объектами происходит на одном экране в планшете. Чтобы устранить это противоречие, были придуманы фрагменты. Хотя там тоже придётся писать много кода.

Несколько слов о том, как проще воспринимать фрагмент. Считайте, что фрагмент — это тот же компонент как Button, TextView или LinearLayout с дополнительными возможностями. Фрагмент, как и кнопку, нужно поместить на экран активности. Но фрагмент является модульным компонентом и один и тот же фрагмент можно встроить в две разные активности. С кнопкой такой номер не пройдёт. Для каждой активности вы должны создать свою отдельную кнопку, даже если их нельзя будет отличить друг от друга.

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

В составе активности есть специальный менеджер фрагментов, который может контролировать все классы фрагментов и управлять ими. О нём позже.

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

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

Имеются специальные виды фрагментов, заточенные под определённые задачи — ListFragment, DialogFragment и другие, которые изучим в других уроках.

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

Второй вариант использует динамическое подключение фрагмента. Принцип следующий — в разметку помещается макет из группы ViewGroup, который становится контейнером для фрагмента. Обычно, для этой цели используют FrameLayout, но это не обязательное условие. И в нужный момент фрагмент замещает контейнер и становится частью разметки.

Поначалу фрагменты кажутся неудобными, так как количество кода увеличивается. Но если с ними работать постоянно, то станет понятнее их принцип.

Реакция разработчиков на появление фрагментов противоречива. Кто-то активно использует их в своих проектах, а кто-то их не переносит и использует альтернативные варианты. Похоже, в стане Гугла также идёт борьба между двумя группами программистов. Фрагменты постоянно развиваются, меняются и дорабатываются.

Первое знакомство

Для первого знакомства создадим стандартный проект на базе Empty Activity и вручную добавим фрагмент. Итак, после создания проекта выбираем из контекстного меню пакета New | Fragment | Fragment (Blank). В диалоговом окне мастера назначаем имя для фрагмента.

На этом этапе создание нового фрагмента напоминает создание новой активности. Мы создаём новый класс и автоматически генерируется макет для него fragment_cat.xml. Единственное отличие, в манифест ничего не добавляется.

Читайте также:  Эплутус зеркало с андроид

Откроем макет фрагмента и немного отредактируем содержимое, добавив центрирование по центру. Также можно было добавить ImageView с изображением кота. Но не будем пока ничего усложнять.

В res/values/strings.xml содержится ресурс hello_blank_fragment. Изменим текст на что-то понятное:

Приготовления закончены. Осталось добавить фрагмент в активность. Открываем activity_main.xml и добавляем новый элемент.

В элементе fragment в атрибуте android:name указываем полное имя класса фрагмента.

Можно запустить проект и увидеть фрагмент внутри активности.

Жизненный цикл фрагмента

У фрагмента есть жизненный цикл, как у активности. Но число методов цикла гораздо больше. Откроем теперь файла класса фрагмента CatFragment и добавим новый код (выделено жирным).

Чтобы увидеть связь между жизненными циклами фрагмента и активности, добавим логи и в активность.

Снова запускаем проект и смотрим логи.

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

Два отдельных фрагмента

Мы научились размещать один фрагмент на экране активности. Ничто не мешает разместить на экране несколько фрагментов, которые являются контейнерами для компонентов. Давайте совместим на одном экране два старых примера — «Hello Kitty» и «Счётчик ворон/котов».

Повторим шаги создания нового фрагмента через готовый шаблон Fragment (Blank) и создадим два новых фрагмента KittyFragment и CounterFragment.

Разметку для KittyFragment копируем из старого примера.

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

Для счётчика котов (ворон больше считать не будем) напишем продвинутую версию, которая позволить не только увеличивать показания счётчика, но и уменьшать. В конце концов коты имеют привычку гулять сами по себе и пропадают из поля нашего зрения.

Разметка для фрагмента counter_fragment.xml.

Код для класса CounterFragment. Здесь также мы добавляем весь код в onViewCreated().

Осталось разместить два фрагмента в activity_main.xml.

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

Источник

Полный список

— используем фрагменты
— разбираемся в их lifecycle

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

В 4-й версии фрагменты никуда не делись, а AVD для 3-й версии какие-то совсем суровые и тяжелые, поэтому для разработки и тестирования будем использовать версию Android 4.1 (API 16). Если у вас нет такой версии в списке доступных, то открывайте Window > Android SDK Manager и скачивайте ее там.

Создадим AVD 4.1

Project name: P1041_FragmentLifecycle
Build Target: Android 4.1
Application name: FragmentLifecycle
Package name: ru.startandroid.develop.p1041fragmentlifecycle
Create Activity: MainActivity

В strings.xml добавим пару строк:

Создадим пару фрагментов. Для этого нам необходимо создать для них layout-файлы и классы с предком android.app.Fragment.

Создаем layout-файлы, как обычно.

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

Теперь классы. Если Activity наследует android.app.Activity, то фрагменты наследуют android.app.Fragment.

Заполняем код. Fragment1.java:

В обоих фрагментах просто выводим в лог вызовы всех lifecycle-методов. Чуть дальше рассмотрим эти методы подробнее.

В методе onCreateView система спрашивает у нас, что ей отображать внутри фрагмента. Мы сообщаем системе, что хотим видеть во фрагменте содержимое соответствующего layout-файла. Для этого мы сами создаем View с помощью inflater и отдаем его системе. Т.е. по смыслу это аналог метода setContentView, который мы вызываем в Activity. Только здесь нам приходится самим создавать View, а не просто передавать идентификатор layout-файла.

Читайте также:  Как установить антивирус для смартфона андроид

Все (layout и классы) для фрагментов готово. Можем поместить их в основной layout-файл Activity. Открываем main.xml, делаем корневым горизонтальный LinearLayout и помещаем в него пару элементов Fragment (вкладка Layouts). При этом появится диалог, в котором надо будет указать какой класс используется для фрагмента.

Указываем для первого класс Fragment1, а для второго Fragment2.

Выровняем фрагменты по ширине с помощью веса. В итоге должен получиться такой main.xml:

В MainActivity.java также добавляем запись в лог всех lifecycle методов:

Все сохраняем. Далее, я сначала запустил эмулятор через AVD, повернул его в горизонтальную ориентацию, затем запустил приложение. Но, в принципе, можно все делать и в вертикальной ориентации. Скрин будет чуть другой, а логи те же.

Все как и заказывали. В горизонтальном LinearLayout размещены пара фрагментов. Содержимое фрагментов взято из layout-файлов fragment1 и fragment2.

Fragment1 onAttach
Fragment1 onCreate
Fragment1 onCreateView
Fragment2 onAttach
Fragment2 onCreate
Fragment2 onCreateView
MainActivity onCreate
Fragment1 onActivityCreated
Fragment2 onActivityCreated
MainActivity onStart
Fragment1 onStart
Fragment2 onStart
MainActivity onResume
Fragment1 onResume
Fragment2 onResume

Первым делом для фрагментов вызываются методы:

onAttach – фрагмент прикреплен к Activity и получает ссылку на него. В дальнейшем мы всегда можем получить ссылку на Activity, вызвав метод getActivity().

onCreate — это аналог метода onCreate у Activity, но здесь мы пока не имеем доступа к UI-элементам

onCreateView – здесь вы создаете View, который будет содержимым фрагмента, и отдаете его системе

Далее срабатывают метод Activity – onCreate, после него метод фрагментов onActivityCreated – сообщает фрагменту о том, что Activity создано и можно работать с UI-элементами

Далее метод Activity – onStart, после него onStart – аналогичен методу Activity, фрагмент виден пользователю

Далее метод Activity – onResume, после него onResume — аналогичен методу Activity, фрагмент доступен для взаимодействия.

Жмем кнопку назад – закрываем приложение:

Fragment1 onPause
Fragment2 onPause
MainActivity onPause
Fragment1 onStop
Fragment2 onStop
MainActivity onStop
Fragment1 onDestroyView
Fragment1 onDestroy
Fragment1 onDetach
Fragment2 onDestroyView
Fragment2 onDestroy
Fragment2 onDetach
MainActivity onDestroy

Сначала для фрагментов и Activity вызываются методы onPause и onStop. Это значит, что фрагменты и Activity более недоступны для взаимодействия, а потом не видны пользователю.

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

onDestroyView – сообщает нам, что View, которое мы создавали в onCreateView, более недоступно

onDestroy – аналог метода onDestroy у Activity

onDetach – фрагмент отсоединен от Activity

И в конце вызывается метод onDestroy для Activity.

Т.е. основные lifecycle методы схожи для Activity и фрагмента. Но есть и некоторые различия, связанные с привязкой фрагмента к Activity.

Фрагменты, так же как и Activity могут сохранять данные при своем пересоздании, например при смене экрана. Для записи используется метод onSaveInstanceState. А прочесть данные можно из Bundle в методах onCreate, onCreateView или onActivityCreated.

А чтобы при пересоздании сохранить сам объект класса Fragment, используйте метод setRetainInstance. Если передать в него true, то при пересоздании фрагмента не будут вызваны методы onDestroy и onCreate, и не будет создан новый экземпляр класса Fragment.

На следующем уроке:

— динамически работаем с фрагментами

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Оцените статью