android - 09 - fragments
DESCRIPTION
Introduction to Fragments APITRANSCRIPT
Fragments
Жилич Роман
Android Internship 2014
О чем речь?
• Fragment – класс, реализующий часть(фрагмент) Activity.
• Позволяет: реализовать гибкий интерфейс, облегчить поддержу разных экранов, декомпозировать и упростить логику.
• Всегда привязан к Activity.• Собственный жизненный цикл, привязанный к циклу
Activity. Подробнее.
На картинках все просто
Основные классыAPI 11+
-android.app.Fragment-android.app.FragmentManager-android.app.FragmentTransaction
API 4+ via SupportLibrary-android.support.v4.app.FragmentActivity-android.support.v4.app.Fragment-android.support.v4.app.FragmentManager-android.support.v4.app.FragmentTransaction
Жизненный цикл
● onAttach(Activity) – вызывается, когда фрагмент привязывается к Activity. С этого момента можно использовать getActivity().
● onCreateView(LayoutInflater, ViewGroup, Bundle) – вызывается, когда фрагмент привязывается к иерархии View.
● onActivityCreated(Bundle) – вызывается, когда завершается onCreate() у Activity.
● onDestroyView() - когда иерархия View разбирается.
● onDetach() - фрагмент больше не ассоциируется с Activity. С этого момента getActivity() возвращает null.
Базовая реализация
● onCreate(Bundle) – инициализируем все ресурсы, связанные с фрагментом, кроме UI.
● onCreateView(LayoutInflater, ViewGroup, Bundle) – создаем и возвращаем View фрагмента. Реализация этого метода не обязательна.
● onActivityCreated(Bundle savedInstanceState) – инициализируем UI, устанавливаем adapter или другие данные.
Базовая реализация
● onResume() - инициализируем “дорогие” ресурсы: GPS, анимация, постоянное использование сети тд.
● onPause() - освобождаем “дорогие” ресурсы, сохраняем состояние.
● onDestoryView() - зануляем все ссылки на все View если мы их сохраняли.
Добавление фрагментов
1. Тег <fragment> в layout.
2. Нельзя убрать.
3. Нельзя передавать аргументы.
4. Обязательно должен быть задан id или tag.
Добавление фрагментов
2. В Runtime с использованием FragmentTransaction
● Fragment.setArguments(Bundle) – Передаем аргументы.
● FragmentManager.beginTransaction() - Создаем транзакцию.
● FragmentManager.executePendingTransactions() - Убеждаемся что все транзакции завершены.
● commit(), commitAllowingStateLoss() - выполняем транзакцию.
● Состояние сохраняется.
Операции с фрагментами
●FragmentManager.findFragmentById(int)●FragmentManager.findFragmentByTag(String)●add(int, Fragment, String)●remove(Fragment)●replace(int, Fragment, String)●hide(Fragment)●show(Fragment)●detach(Fragment) API 13●attach(Fragment) API 13
●С фрагментами задекларированными в layout почти ничего делать нельзя.
Backstack
●FragmentTransaction.addToBackStack(String).●FragmentManager.popBackStack().●FragmentManager.getBackStackEntryCount()●FragmentManager.getBackStackEntryAt(int)●По возвращению из стека onCreateView(), onActivityCreated(), onStart(), and onResume().●Поведение FragmentActivity по умолчанию:
if (!fragmentManager.popBackStackImmediate()) {
finish();
}
Сохранение состояния●Нельзя хранить ссылки на элементы layout.
●Сохраняется в onSaveInstanceState(Bundle)
●Восстанавливается если savedState не null в onCreate(), onCreateView(), и onActivityCreated().
●Можно переиспользовать: setRetainInstance(true).
●findFragment…
●Fragment.getActivity(): findViewById, get..., cast и тд.
●Interfaces.
●Fragment.setTargetFragment(Fragment, int), Fragment.getTargetRequestCode(), Fragment.getTargetFragment().
●Events: EventBus, Intents/LocalBroadcastReceiver
Fragment vs. Fragment\Activity
Наследники
●DialogFragment●ListFragment●PreferenceFragment нет в SupportLibrary●WebViewFragment нет в SupportLibrary●MapFragment из Google Services
●ViewPager + FragmentPagerAdapter
Вложенные фрагменты
API 17
●Fragment.getChildFragmentManager()●Fragment.getParentFragment()●Состояние сохраняется. ●Жизненный цикл onCreateView() onDestroyView()●Проблемы с анимацией.●Нельзя использовать setRetainInstance(boolean)●Да и вообще не очень...
Делайте правильно, а не правильно - не делайте
Хорошо:
● newInstance(...)● setArguments()● Все диалоги – фрагменты● Хорошее разделение по смыслу: один фрагмент – одна задача.● Сохранять состояние.● Утилитные классы для избежания копипасты.● ListFragment, WebViewFragment.
Делайте правильно, а не правильно - не делайте
Плохо, иногда очень:
● Отсутствие пустого конструктора.
● Забытые ссылки на элементы layout.
● Забытые вложенные анонимные классы, асинхронные задачи и тд.
● Вложенные фрагменты пересоздаются, даже если состояние родительского восстанавливается.
Ссылки
● API Guides
● Google Fragment Training
● Fragment
● FragmentTransaction
● FragmentManager
● FragmentPagerAdapter