В разработке для Android одним из самых важных компонентов является активность. Активность представляет собой экран, который предоставляет пользовательский интерфейс (ui) и поэтому необходим практически для любого приложения Android. Фрагмент очень похож на активность в том, что он делает многое из того, что делает активность:
- Они оба являются экранами, которые предоставляют пользовательский интерфейс.
- Они оба определяют и управляют собственными макетами.
- Управляйте собственными жизненными циклами.
- Обрабатывайте собственные события ввода.
При этом фрагмент отличается от действия несколькими способами:
- Живучесть — в отличие от действия, для выживания фрагменту требуется хост, который может быть либо действием, либо даже другим фрагментом.
- Модульность — действие представляет собой один экран целиком, а фрагмент занимает часть экрана действий (также может занимать все действие целиком). Что позволяет использовать более модульный пользовательский интерфейс.
- Повторное использование — Фрагмент может иметь более одного хоста. Например, вы можете захотеть использовать одно и то же представление Recycler в различных действиях.
Именно эти различия делают фрагменты такими полезными. Фрагмент воспринимается как гость для своего хоста (т. е. действий), это означает, что как гость фрагмент может быть добавлен, удален, заменен и т. д. с его хоста по усмотрению разработчика. Модульность и возможность повторного использования также позволяют разработчику создавать гораздо более динамичные интерфейсы.
В этой статье я покажу вам, как создать фрагмент, создав очень простое приложение. Приложение будет состоять из действия, состоящего из нижней панели навигации с двумя выбираемыми элементами. Один из двух фрагментов будет отображаться в зависимости от того, какой Item выбран пользователем.
Предварительные требования:
- Android Studio (если у вас его нет, вы можете получить его здесь).
- Знание языка программирования Kotlin (рекомендуется) или Java. В этом руководстве используется Kotlin.
Шаг 1. Подготовка
- Загрузите Android Studio и создайте новый проект.
- Выберите Пустые действия.
- В окне Configure Your Project назовите свой проект «Android Fragment» (без кавычек) и нажмите «Готово».
Шаг 2. Настройте проект
Прежде чем вы сможете использовать фрагменты в своем проекте, вы должны убедиться, что ваш проект правильно настроен:
- Сначала убедитесь, что в вашем проекте есть репозиторий Google Maven. Если он не добавит его в ваш файл settings.gradle.
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() ...
- Добавьте следующие зависимости (если их еще нет) в файл build.gradle уровня вашего модуля.
dependencies { def fragment_version = "1.5.3 implementation ("androidx.fragment:fragment-ktx:$fragment_version") implementation 'com.google.android.material:material:1.7.0' }
- Наконец, синхронизируйте свой проект.
Шаг 3. Создайте макет активности
После завершения синхронизации вы можете создать свой макет. Это должно выглядеть так:
?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.fragment.app.FragmentContainerView android:id="@+id/fragmentContainerView" android:name="com.example.androidfragment.FragmentOne" android:layout_width="253dp" android:layout_height="407dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_navigation_view" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:menu="@menu/bottom_navigation_menu" /> </androidx.constraintlayout.widget.ConstraintLayout>
Макет активности будет состоять из FragmentContainerView, который представляет собой настраиваемый макет, специально отображающий фрагменты. Этот макет удобен, потому что он может легко изменить, какой фрагмент он содержит.
Макет также состоит из BottomNavigationView.На этой нижней панели отображается Меню, которое будет содержать два наших элемента, но ошибка будет быть показано, потому что мы еще не создали меню:
- щелкните правой кнопкой мыши папку res в папке приложения и выберите Создать ›Файл ресурсов Android.
- в окне Новый файл ресурсов назовите файл «bottom_navigation_menu» (без кавычек).
- измените значение в поле Тип ресурса на меню в раскрывающемся списке поля Тип ресурса.
- оставьте все как есть и нажмите ок.
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="https://schemas.android.com/apk/res/android"> <item android:id="@+id/item1" android:enabled="true" android:title="Fragment One"/> <item android:id="@+id/item2" android:enabled="true" android:title="Fragment Two"/> </menu>
- Переключитесь на Mактивность и добавьте этот код в метод OnCreate.
val bottomNavigationView:BottomNavigationView = findViewById(R.id.bottom_navigation_view) bottomNavigationView.setOnItemSelectedListener { item -> when(item.itemId) { R.id.item1 -> { // Respond to navigation item 1 click showFragment(FragmentOne.newInstance()) true } R.id.item2 -> { // Respond to navigation item 2 click showFragment(FragmentTwo.newInstance()) true } else -> false } } }
В приведенном выше коде мы установили OnItemSelectedListener или наше нижнее представление навигации. Это позволит нам реализовать наше поведение переключения между фрагментами.
В двух вариантах выражения when мы вызываем метод showFragment и устанавливаем в них экземпляры наших двух еще не созданных фрагментов. Будет показана ошибка, потому что мы еще не создали ни метод (showFragment), ни классы фрагментов для получения их экземпляров.
Сначала мы создадим наши фрагменты.
Шаг 4. Создайте фрагменты
. Сначала щелкните окно проекта в Android Studio, щелкните правой кнопкой мыши папку app и выберите Создать › Фрагмент › Фрагмент (пустой).
- Назовите фрагмент «FragmentOne» (без кавычек) и оставьте все остальное как есть.
- Нажмите «Готово».
- Создайте еще один фрагмент и назовите его «FragmentTwo» (без кавычек).
Шаг 4. Изменение фрагментов
Ваш класс Fragment будет выглядеть так:
package com.example.androidfragment import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private const val ARG_PARAM1 = "param1" private const val ARG_PARAM2 = "param2" /** * A simple [Fragment] subclass. * Use the [FragmentOne.newInstance] factory method to * create an instance of this fragment. */ class FragmentOne : Fragment() { // TODO: Rename and change types of parameters private var param1: String? = null private var param2: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { param1 = it.getString(ARG_PARAM1) param2 = it.getString(ARG_PARAM2) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_one, container, false) } companion object { /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @param param2 Parameter 2. * @return A new instance of fragment MyFragment. */ // TODO: Rename and change types and number of parameters @JvmStatic fun newInstance(param1: String, param2: String) = FragmentOne().apply { arguments = Bundle().apply { putString(ARG_PARAM1, param1) putString(ARG_PARAM2, param2) } } }
Мы скоро перейдем к функциональности класса, сначала давайте поработаем над тем, как класс выглядит.
- Перейдите к файлу макета fragment_one.
- Вставьте TextView в середину макета, он должен читать «это фрагмент один» (без кавычек).
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".FragmentOne"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="This is fragment one" android:layout_gravity="center"/> </FrameLayout>
Теперь вернитесь к классу FragmentOne.kt.
package com.example.androidfragment import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private const val ARG_PARAM1 = "param1" private const val ARG_PARAM2 = "param2" /** * A simple [Fragment] subclass. * Use the [FragmentOne.newInstance] factory method to * create an instance of this fragment. */ class FragmentOne : Fragment() { // TODO: Rename and change types of parameters private var param1: String? = null private var param2: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) arguments?.let { param1 = it.getString(ARG_PARAM1) param2 = it.getString(ARG_PARAM2) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_one, container, false) } companion object { /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @param param2 Parameter 2. * @return A new instance of fragment MyFragment. */ // TODO: Rename and change types and number of parameters @JvmStatic fun newInstance() = FragmentOne()apply { arguments = Bundle().apply { putString(ARG_PARAM1, param1) putString(ARG_PARAM2, param2) } }
Этот шаблон просто состоит из методов жизненного циклаOnCreate и OnCreateView (подробнее о жизненном цикле фрагмента читайте здесь), двух глобальных строковых переменных и сопутствующей объектной функции ( newInstance), который возвращает экземпляр класса. Нам не потребуются никакие параметры в нашей функции newInstance, поэтому удалите их.
Теперь функция должна выглядеть так:
companion object { /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @param param2 Parameter 2. * @return A new instance of fragment MyFragment. */ // TODO: Rename and change types and number of parameters @JvmStatic fun newInstance() = FragmentOne() }
Сделайте то же самое для fragmentTwo и теперь перейдите к классу Main Activity.
Шаг 5. Измените основное действие
Наконец, для подключения наших фрагментов к основному действию мы будем использовать Диспетчер фрагментов. Диспетчер фрагментов — это класс, отвечающий за выполнение действий (называемых транзакциями) над фрагментами вашего приложения, таких как их добавление, удаление или замена, а также добавление их в резервный стек.
Вне метода OnCreate:
- Создайте наш закрытый метод «showFragment» (без кавычек).
Эта функция примет фрагмент в качестве параметра и при вызове будет использовать метод замены Fragment Manager.
private fun showFragment(fragment: Fragment) { supportFragmentManager.commit { replace(R.id.fragmentContainerView, fragment) } }
Метод replace будет использовать наш параметр фрагмента.
Шаг 6. Запустите приложение
Запустите приложение, и это должно отображаться:
И когда вы нажимаете Фрагмент два:
Вот и все!
Это очень простая реализация фрагментов Android, но существуют различные способы, которыми ваши фрагменты могут помочь вам в разработке приложения для Android. Узнайте больше о фрагментах Android, их использовании и преимуществах на официальном сайте документации Android здесь.