Создать фрагмент,Создать фрагмент

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

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

Настройте свою среду

Фрагменты требуют зависимости от библиотеки фрагментов AndroidX . Вам необходимо добавить репозиторий Google Maven в файл settings.gradle вашего проекта, чтобы включить эту зависимость.

dependencyResolutionManagement {
    repositoriesMode
.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories
{
        google
()
       
...
   
}
}
dependencyResolutionManagement {
    repositoriesMode
.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories
{
        google
()
       
...
   
}
}

Чтобы включить библиотеку фрагментов AndroidX в свой проект, добавьте следующие зависимости в файл build.gradle вашего приложения:

dependencies {
    def fragment_version = "1.8.4"

    // Java language implementation
    implementation "androidx.fragment:fragment:$fragment_version"
    // Kotlin
    implementation "androidx.fragment:fragment-ktx:$fragment_version"
}
dependencies {
    val fragment_version = "1.8.4"

    // Java language implementation
    implementation("androidx.fragment:fragment:$fragment_version")
    // Kotlin
    implementation("androidx.fragment:fragment-ktx:$fragment_version")
}

Создать класс фрагмента

Чтобы создать фрагмент, расширьте класс AndroidX Fragment и переопределите его методы, чтобы вставить логику вашего приложения, аналогично тому, как вы создаете класс Activity . Чтобы создать минимальный фрагмент, определяющий собственный макет, предоставьте ресурс макета вашего фрагмента базовому конструктору, как показано в следующем примере:

class ExampleFragment : Fragment(R.layout.example_fragment)
class ExampleFragment extends Fragment {
   
public ExampleFragment() {
       
super(R.layout.example_fragment);
   
}
}

Библиотека Fragment также предоставляет более специализированные базовые классы фрагментов:

DialogFragment
Отображает плавающее диалоговое окно. Использование этого класса для создания диалога является хорошей альтернативой использованию вспомогательных методов диалога в классе Activity , поскольку фрагменты автоматически обрабатывают создание и очистку Dialog . Дополнительные сведения см. в разделе Отображение диалогов с помощью DialogFragment .
PreferenceFragmentCompat
Отображает иерархию объектов Preference в виде списка. Вы можете использовать PreferenceFragmentCompat для создания экрана настроек для вашего приложения.

Добавить фрагмент в действие

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

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

Добавить фрагмент через XML

Чтобы декларативно добавить фрагмент в XML-макет вашего действия, используйте элемент FragmentContainerView .

Вот пример макета активности, содержащий один FragmentContainerView :

<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
   
xmlns:android="http://schemas.android.com/apk/res/android"
   
android:id="@+id/fragment_container_view"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
android:name="com.example.ExampleFragment" />

Атрибут android:name указывает имя класса Fragment , экземпляр которого требуется создать. Когда макет действия раздувается, создается экземпляр указанного фрагмента, для вновь созданного фрагмента вызывается onInflate() и создается FragmentTransaction для добавления фрагмента в FragmentManager .

Добавить фрагмент программно

Чтобы программно добавить фрагмент в макет вашей активности, макет должен включать FragmentContainerView который будет служить контейнером фрагмента, как показано в следующем примере:

<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
   
xmlns:android="http://schemas.android.com/apk/res/android"
   
android:id="@+id/fragment_container_view"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent" />

В отличие от подхода XML, атрибут android:name здесь не используется в FragmentContainerView , поэтому автоматически не создается конкретный фрагмент. Вместо этого используется FragmentTransaction для создания экземпляра фрагмента и добавления его в макет действия.

Пока ваша деятельность выполняется, вы можете выполнять транзакции с фрагментами, такие как добавление, удаление или замена фрагмента. В вашем FragmentActivity вы можете получить экземпляр FragmentManager , который можно использовать для создания FragmentTransaction . Затем вы можете создать экземпляр своего фрагмента в методе onCreate() вашей активности с помощью FragmentTransaction.add() , передав идентификатор ViewGroup контейнера в вашем макете и класс фрагмента, который вы хотите добавить, а затем зафиксировать транзакцию, как показано в следующий пример:

class ExampleActivity : AppCompatActivity(R.layout.example_activity) {
   
override fun onCreate(savedInstanceState: Bundle?) {
       
super.onCreate(savedInstanceState)
       
if (savedInstanceState == null) {
            supportFragmentManager
.commit {
                setReorderingAllowed
(true)
                add
<ExampleFragment>(R.id.fragment_container_view)
           
}
       
}
   
}
}
public class ExampleActivity extends AppCompatActivity {
   
public ExampleActivity() {
       
super(R.layout.example_activity);
   
}
   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
if (savedInstanceState == null) {
            getSupportFragmentManager
().beginTransaction()
               
.setReorderingAllowed(true)
               
.add(R.id.fragment_container_view, ExampleFragment.class, null)
               
.commit();
       
}
   
}
}

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

Если вашему фрагменту требуются некоторые исходные данные, аргументы можно передать вашему фрагменту, указав Bundle в вызове FragmentTransaction.add() , как показано ниже:

class ExampleActivity : AppCompatActivity(R.layout.example_activity) {
     
override fun onCreate(savedInstanceState: Bundle?) {
       
super.onCreate(savedInstanceState)
       
if (savedInstanceState == null) {
           
val bundle = bundleOf("some_int" to 0)
            supportFragmentManager
.commit {
                setReorderingAllowed
(true)
                add
<ExampleFragment>(R.id.fragment_container_view, args = bundle)
           
}

       
}
   
}
}
public class ExampleActivity extends AppCompatActivity {
   
public ExampleActivity() {
       
super(R.layout.example_activity);
   
}
   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
if (savedInstanceState == null) {
           
Bundle bundle = new Bundle();
            bundle
.putInt("some_int", 0);

            getSupportFragmentManager
().beginTransaction()
               
.setReorderingAllowed(true)
               
.add(R.id.fragment_container_view, ExampleFragment.class, bundle)
               
.commit();

       
}
   
}
}

Затем аргументы Bundle можно получить из вашего фрагмента, вызвав requireArguments() , а для получения каждого аргумента можно использовать соответствующие методы получения Bundle .

class ExampleFragment : Fragment(R.layout.example_fragment) {
   
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
       
val someInt = requireArguments().getInt("some_int")
       
...
   
}
}
class ExampleFragment extends Fragment {
   
public ExampleFragment() {
       
super(R.layout.example_fragment);
   
}

   
@Override
   
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
       
int someInt = requireArguments().getInt("some_int");
       
...
   
}
}

См. также

Транзакции фрагментов и FragmentManager более подробно рассмотрены в руководстве по диспетчеру фрагментов .