List all fragments android

ListFragment. Основы

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

Представим себе ситуацию — у нас есть список ListView, содержащий ссылки. При щелчке на одной из ссылок мы открываем вторую активность, состоящую из какого-нибудь компонента: TextView или WebView. По сути, один экран у нас сменяется другим. Можно реализовать эту задачу по другому. На планшетах много места. Почему бы не расположить ListView и TextView на одном экране рядышком? И когда пользователь будет щёлкать слева на элементе списка, то в правой части будет обновляться содержимое TextView. Такой подход нам знаком, например, при чтении электронных писем — слева список писем, а справа — содержание выбранного письма.

Для связывания данных используются адаптеры ListAdapter, ArrayAdapter, SimpleAdapter, SimpleCursorAdapter и т.д. Подключение следует производить в методе onActivityCreated().

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

Начнём с простых примеров. Мы знаем, что для создания списка используется компонент ListView. Если наш экран должен состоять только из списка, то можно использовать готовую активность ListActivity, в которой уже встроен список и реализованы необходимые методы.

ListFragment работает по такому же принципу. По сути это обычный фрагмент, в который встроили ListView, избавив нас от написания лишнего кода.

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

Как правило, ListFragment используют в паре с другим обычным фрагментом. А пока мы попробуем обойтись одним фрагментом. Создайте новый проект или используйте уже готовый проект и добавьте новый класс, который наследуется от ListFragment. Назовём новый класс SingleListFragment:

Как и с обычными фрагментами, списочный фрагмент может быть из библиотеки поддержки или из обычных классов Android.

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

Разместим фрагмент в разметке основной активности MainActivity. У нас это файл activity_main.xml:

В атрибуте android:name вы указываете полное имя класса вашего фрагмента. Вы можете переключиться в графический режим и из контекстного меню выбрать пункт list_content, чтобы увидеть экран со списком. Ничего необычного и интересного.

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

Не будем ничего выдумывать, а просто скопируем массив строк из урока про ListView и вставим его в класс фрагмента. А в методе onActivityCreated() свяжем массив с адаптером и передадим его списочному фрагменту.

Мы используем метод onActivityCreated(), так как именно здесь можно быть уверенным, что все необходимые компоненты фрагмента загрузились и фрагмент готов к использованию в составе активности. Метод onCreateView() в данном случае использовать не обязательно. В остальном код идентичен с кодом для ListActivity — массив, адаптер, связывание массива с адаптером.

Читайте также:  Sdcard это папка android

Запускаем проект и видим список с именами котов.

Если вы хотите видеть выбранный элемент постоянно активным, то используйте другую системную разметку simple_list_item_activated_1.

Если нужна своя разметка для списка, то поступаем точно также, как в уроке с ListActivity. Создаём в папке res/layout новый файл, скажем listfragment.xml и размещаем нужные элементы:

В шаблоне нужно разместить ListView с обязательным идентификатором @id/android:list. Компонент TextView будет показан в том случае, если нет данных для списка. Он также должен иметь обязательный идентификатор @id/android:empty. Помните, в начале статьи я приводил исходник системного фрагмента?

Разметка подключается в методе onCreateView():

Запустив проект, мы увидим список с зелёным фоном. Если отключить адаптер, то можно увидеть уже свой компонент TextView со своим текстом, который вы определили в ресурсе @string/empty.

Если в ListView вы добавите атрибут android:choiceMode=»singleChoice» для одиночного выбора, то в адаптере рекомендую использовать другой ресурс android.R.layout.simple_list_item_activated_1. В этом случае выбранный элемента списка будет иметь другой цвет, что позволит быстро определять выделенный элемент.

Нажатия на элементах списка

Определять нажатия на отдельных элементах списка можно через метод фрагмента onListItemClick():

Если вас интересует текст выбранного элемента:

Если вы хотите настраивать внешний вид каждого элемента, например, разместить значок, то опять ничего нового здесь нет. Нужно создать свою разметку для элемента списка и написать свой адаптер. Простой пример. Создадим новую разметку res/layout/listfragment_row.xml:

В классе фрагмента прописываем свой адаптер. В методе onActivityCreated() присоединяем свой адаптер, а в методе onListItemClick() меняем код.

Множественный выбор

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

listfragment.xml

В классе фрагмента напишем код, заменив системную разметку на simple_list_item_multiple_choice.

Сам ListFragment отдельно использовать смысла нет, поэтому во второй части рассмотрим пример с двумя фрагментами.

Источник

Фрагменты

Существует два основных подхода в использовании фрагментов.

Первый способ основан на замещении родительского контейнера. Создаётся стандартная разметка и в том месте, где будут использоваться фрагменты, размещается контейнер, например, FrameLayout. В коде контейнер замещается фрагментом. При использовании подобного сценария в разметке не используется тег fragment, так как его нельзя менять динамически. Также вам придётся обновлять ActionBar, если он зависит от фрагмента. Здесь показан такой пример.

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

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

Основные классы

Сами фрагменты наследуются от androidx.fragment.app.Fragment. Существует подклассы фрагментов: ListFragment, DialogFragment, PreferenceFragment, WebViewFragment и др. Не исключено, что число классов будет увеличиваться, например, появился ещё один класс MapFragment.

Читайте также:  Как узнать ios или android

Для взаимодействия между фрагментами используется класс android.app.FragmentManager — специальный менеджер по фрагментам.

Как в любом офисе, спецманагер не делает работу своими руками, а использует помощников. Например, для транзакций (добавление, удаление, замена) используется класс-помощник android.app.FragmentTransaction.

Для сравнения приведу названия классов из библиотеки совместимости:

  • android.support.v4.app.FragmentActivity
  • android.support.v4.app.Fragment
  • android.support.v4.app.FragmentManager
  • android.support.v4.app.FragmentTransaction

Как видите, разница в одном классе, который я привёл первым. Он используется вместо стандартного Activity, чтобы система поняла, что придётся работать с фрагментами. На данный момент студия создаёт проект на основе ActionBarActivity, который является подклассом FragmentActivity.

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

В 2018 году Гугл объявила фрагменты из пакета androd.app устаревшими. Заменяйте везде на версию из библиотеки совместимости. В 2020 году уже используют пакет androidx.fragment.app.

В версии Support Library 27.1.0 появились новые методы requireActivity() и requireContext(), которые пригодятся при написании кода, когда требуется наличие активности и нужно избежать ошибки на null.

Общий алгоритм работы с фрагментами будет следующим:

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

Также, как в активности, вы создаёте различные методы типа onCreate() и т.д. Если фрагмент имеет разметку, то используется метод onCreateView() — считайте его аналогом метода setContentView(), в котором вы подключали разметку активности. При этом метод onCreateView() возвращает объект View, который является корневым элементом разметки фрагмента.

Разметку для фрагмента можно создать программно или декларативно через XML.

Создание разметки для фрагмента ничем не отличается от создания разметки для активности. Вот отрывок кода из метода onCreateView():

Глядя на этот код, вы должные понять, что фрагмент использует разметку из файла res/layout/first_fragment.xml, которая содержит кнопку с идентификатором android:id=»@+id/button_first». Здесь также прослеживается сходство с подключением компонентов в активности. Обратите внимание, что перед методом findViewById() используется view, так как этот метод относится к компоненту, а не к активности, как мы обычно делали в программах, когда просто опускали имя активности. Т.е. в нашем случае мы ищем ссылку на кнопку не среди разметки активности, а внутри разметки самого фрагмента.

Нужно помнить, что в методе inflate() последний параметр должен иметь значение false в большинстве случаев.

FragmentManager

Класс FragmentManager имеет два метода, позволяющих найти фрагмент, который связан с активностью:

findFragmentById(int id) Находит фрагмент по идентификатору findFragmentByTag(String tag) Находит фрагмент по заданному тегу

Методы транзакции

Мы уже использовали некоторые методы класса FragmentTransaction. Познакомимся с ними поближе

add() Добавляет фрагмент к активности remove() Удаляет фрагмент из активности replace() Заменяет один фрагмент на другой hide() Прячет фрагмент (делает невидимым на экране) show() Выводит скрытый фрагмент на экран detach() (API 13) Отсоединяет фрагмент от графического интерфейса, но экземпляр класса сохраняется attach() (API 13) Присоединяет фрагмент, который был отсоединён методом detach()

Методы remove(), replace(), detach(), attach() не применимы к статичным фрагментам.

Перед началом транзакции нужно получить экземпляр FragmentTransaction через метод FragmentManager.beginTransaction(). Далее вызываются различные методы для управления фрагментами.

Читайте также:  Как найти путь sdcard android obb

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

Аргументы фрагмента

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

  • Активность может создать фрагмент и установить аргументы для него
  • Активность может вызвать методы экземпляра фрагмента
  • Фрагмент может реализовать интерфейс, который будет использован в активности в виде слушателя

Фрагмент должен иметь только один пустой конструктор без аргументов. Но можно создать статический newInstance с аргументами через метод setArguments().

Доступ к аргументам можно получить в методе onCreate() фрагмента:

Динамически загружаем фрагмент в активность.

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

Вызываем метод в активности:

Если фрагмент должен сообщить о своих действиях активности, то следует реализовать интерфейс.

Управление стеком фрагментов

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

Чтобы добавить транзакцию в стек, вызовите метод FragmentTransaction.addToBackStack(String) перед завершением транзакции (commit). Строковый аргумент — опциональное имя для идентификации стека или null. Класс FragmentManager имеет метод popBackStack(), возвращающий предыдущее состояние стека по этому имени.

Если вы вызовете метод addToBackStack() при удалении или замещении фрагмента, то будут вызваны методы фрагмента onPause(), onStop(), onDestroyView().

Когда пользователь нажимает на кнопку возврата, то вызываются методы фрагмента onCreateView(), onActivityCreated(), onStart() и onResume().

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

Теперь в классе фрагмента прописываем метод с нужным кодом.

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

Интеграция Action Bar/Options Menu

Фрагменты могут добавлять свои элементы в панель действий или меню активности. Сначала вы должны вызвать метод Fragment.setHasOptionsMenu() в методе фрагмента onCreate(). Затем нужно задать настройки для методов фрагмента onCreateOptionsMenu() и onOptionsItemSelected(), а также при необходимости для методов onPrepareOptionsMenu(), onOptionsMenuClosed(), onDestroyOptionsMenu(). Работа методов фрагмента ничем не отличается от аналогичных методов для активности.

В активности, которая содержит фрагмент, данные методы автоматически сработают.

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

Код для активности:

Код для фрагмента:

Связь между фрагментом и активностью

Экземпляр фрагмента связан с активностью. Активность может вызывать методы фрагмента через ссылку на объект фрагмента. Доступ к фрагменту можно получить через методы findFragmentById() или findFragmentByTag().

Источник

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