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

Последнее обновление: 17.10.2021

Каждый класс фрагмента наследуется от базового класса Fragment и имеет свой жизненный цикл, состоящий из ряда этапов:

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

Каждый этап жизненного цикла описывается одной из констант перечисления Lifecycle.State:

  • INITIALIZED

  • CREATED

  • STARTED

  • RESUMED

  • DESTROYED

Стоит отметить, что представление фрагмента (его визуальный интерфейс или View) имеет отдельный жизненный цикл.

  • При создании фрагмент находится в состоянии INITIALIZED. Чтобы фрагмент прошел все остальные этапы жизненного цикла, фрагмент необходимо передать в объект FragmentManager, который далее определяет состояние фрагмента и переводит фрагмент из одного состояния в другое.

  • onCreate(): происходит создание фрагмента. В этом методе мы можем получить ранее сохраненное состояние фрагмента через параметр метода Bundle savedInstanceState. (Если фрагмент создается первый раз, то этот объект имеет значение null) Этот метод вызывается после вызова соответствующего метода onCreate() у activity.

    public void onCreate(Bundle savedInstanceState)
  • onCreateView(): фрагмент создает представление (View или визуальный интерфейс). В этом методе мы можем установить, какой именно изуальный интерфейс будет использовать фрагмент. При выполнении этого метода представление фрагмента переходит в состояние INITIALIZED. А сам фрагмент все еще находится в состоянии CREATED

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    

    Первый параметр - объект LayoutInflater позволяет получить содержимое ресурса layout и передать его во фрагмент.

    Второй параметр - объект ViewGroup представляет контейнер, в которой будет загружаться фрагмент.

    Третий параметр - объект Bundle представляет состояние фрагмента. (Если фрагмент загружается первый раз, то равен null)

    На выходе метод возвращает созданное с помощью LayoutInflater представление в виде объекта View - собственно представление фрагмента

  • onViewCreated(): вызывается после создания представления фрагмента.

    public void onViewCreated (View view,  Bundle savedInstanceState)
    

    Первый параметр - объект View - представление фрагмента, которое было создано посредством метода onCreateView.

    Второй параметр - объект Bundle представляет состояние фрагмента. (Если фрагмент загружается первый раз, то равен null)

  • onViewStateRestored(): получает состояние представления фрагмента. После выполнения этого метода представление фрагмента переходит в состояние CREATED

    public void onViewStateRestored (Bundle savedInstanceState)
    
  • onStart(): вызывается, когда фрагмент становится видимым и вместе с представлением переходит в состояние STARTED

    public void onStart ()
    
  • onResume(): вызывается, когда фрагмент становится активным, и пользователь может с ним взаимодействовать. При этом фрагмент и его представление переходят в состояние RESUMED

    public void onResume ()
    
  • onPause(): фрагмент продолжает оставаться видимым, но уже не активен и вместе с представлением переходит в состояние STARTED

    public void onPause ()
    
  • onStop(): фрагмент больше не является видимым и вместе с представлением переходит в состояние CREATED

    public void onStop ()
    

    На этом этапе жизненного цикла мы можем сохранить состояние фрагмента с помощью метода onSaveInstanceState(). Однако стоит учитывать, что вызов этого метода зависит от версии API. До API 28 onSaveInstanceState() вызывается до onStop(), а начиная API 28 после onStop().

  • onDestroyView(): уничтожается представление фрагмента. Представление переходит в состояние DESTROYED

  • onDestroy(): окончательно уничтожение фрагмента - он также переходит в состояние DESTROYED

Дополнительно для фрагмента определено два метода обратного вызова, которые связаны с прикреплением фрагмента к activity:

  • Когда фрагмент добавляется в FragmentManager и прикрепляется к определенному классу Activity, у фрагмента вызывается метод onAttach(). Данный метод вызывается до всех остальных методов жизненного цикла. Начиная с этого момента фрагмент становится активным, и FragmentManager начинает управлять его жизненным циклом.

  • Метод onDetach() вызывается, когда фрагмент удаляется из FragmentManager и открепляется от класса Activity. Этот метод вызывается после всех остальных методов жизненного цикла.

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

Fragment Lifecycle жизненный цикл фрагмента в Android Studio и Java

В каталоге res/layout определен файл layout для фрагмента - fragment_content.xml со следующей разметкой:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/updateButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Обновить"
        app:layout_constraintBottom_toTopOf="@+id/dateTextView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/dateTextView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textSize="26sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/updateButton" />

</androidx.constraintlayout.widget.ConstraintLayout>

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

package com.example.fragmentapp;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.util.Log;

import java.util.Date;

public class ContentFragment extends Fragment {

    private final static String TAG = "ContentFragment";

    public ContentFragment(){
        Log.d(TAG, "Constructor");
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        Log.d(TAG, "onAttach");
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView");
        return inflater.inflate(R.layout.fragment_content, container, false);
    }
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Button updateButton = view.findViewById(R.id.updateButton);
        TextView updateBox = view.findViewById(R.id.dateTextView);

        updateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String curDate = new Date().toString();
                updateBox.setText(curDate);
            }
        });
        Log.d(TAG, "onViewCreated");
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
        Log.d(TAG, "onViewStateRestored");
    }

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart");
    }

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(TAG, "onDestroyView");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG, "onDetach");
    }
}

В отличие от прошлой статьи, где рассматривалось создание фрагмента, здесь фрагмент устанавливает представление в методе onCreateView. Для этого в метод inflate() объекта LayoutInflater передается идентификатор ресурса layout и контейнер - объект ViewGroup, в который будет загружаться фрагмент. В итоге метод inflate() возвращает созданное представление.

return inflater.inflate(R.layout.fragment_content, container, false);

При выполнении метода onViewCreated() представление уже создано и оно передается в качестве первого параметра - объекта View, через который с помощью идентификаторов мы можем получить визуальные элементы - TextView и Button, которые определены в представлении.

Для остальных методов жизненного цикла установлено простое логгирование с помощью метода Log.d().

Пусть в файле activity_main.xml происходит добавление фрагмента:

<?xml version="1.0" encoding="utf-8"?>
<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.fragmentapp.ContentFragment" />

И класс MainActivity:

package com.example.fragmentapp;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

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

Жизненный цикл фрагмента в Android Studio и Java, onViewCreated

А в окне Logcat в Android Studio можно будет наблюдать логгирование методов жизненного цикла

Методы и состояния хизненного цикла фрагмента в Android Studio и Java
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850