Поиск по сайту:

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


Сегодня мы узнаем о жизненном цикле фрагментов Android и реализуем один класс активности, состоящий из двух фрагментов, в приложении для Android.

Android-фрагмент

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

  1. onAttach(): этот метод будет вызываться первым, еще до onCreate(), сообщая нам, что ваш фрагмент был присоединен к действию. Вам передается Activity, в котором будет размещаться ваш фрагмент
  2. onCreateView(): система вызывает этот обратный вызов, когда фрагменту нужно впервые отрисовать свой пользовательский интерфейс. Чтобы отрисовать пользовательский интерфейс для фрагмента, компонент View должен быть возвращен из этого метода, который является корнем макета фрагмента. Мы можем вернуть null, если фрагмент не предоставляет пользовательский интерфейс.
  3. onViewCreated(): будет вызываться после onCreateView(). Это особенно полезно при наследовании реализации onCreateView(), но нам необходимо настроить результирующие представления, например, с помощью ListFragment и когда настроить адаптер
  4. onActivityCreated(): будет вызываться после onCreate() и onCreateView(), чтобы указать, что действие onCreate() завершено. Если есть что-то, что необходимо инициализировать во фрагменте, который зависит от завершения работы onCreate() активности, то для этой работы по инициализации можно использовать onActivityCreated()
  5. onStart(): метод onStart() вызывается, как только фрагмент становится видимым
  6. onPause(): система вызывает этот метод как первое указание на то, что пользователь покидает фрагмент. Обычно именно здесь вы должны зафиксировать любые изменения, которые должны сохраняться за пределами текущего сеанса пользователя.
  7. onStop(): фрагмент будет остановлен вызовом onStop()
  8. onDestroyView(): вызывается перед onDestroy(). Это аналог onCreateView(), где мы настраиваем пользовательский интерфейс. Если есть вещи, которые необходимо очистить для пользовательского интерфейса, то эту логику можно добавить в onDestroyView()
  9. onDestroy() : onDestroy() вызывается для окончательной очистки состояния фрагмента, но не гарантируется, что он будет вызван платформой Android.
  10. onDetach() : вызывается после onDestroy(), чтобы уведомить о том, что фрагмент больше не связан с хостингом.

Классы фрагментов Android

В Android API в Honeycomb (API 11) были добавлены фрагменты.

  1. android.app.Fragment : базовый класс для всех определений фрагментов
  2. android.app.FragmentManager : класс для взаимодействия с объектами-фрагментами внутри действия.
  3. android.app.FragmentTransaction : класс для выполнения атомарного набора операций с фрагментами. При использовании библиотеки пакетов совместимости, предоставленной Google, для реализации используются следующие классы.

  • android.support.v4.app.FragmentActivity : базовый класс для всех действий, использующих функции фрагмента (и загрузчика) на основе совместимости
  • android.support.v4.app.Fragment
  • android.support.v4.app.FragmentManager
  • android.support.v4.app.FragmentTransaction

Фрагмент Android onCreateView()

Вот пример фрагмента, использующего onCreateView() для его реализации:

public class SampleFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parentViewGroup,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_sample, parentViewGroup, false);
        return rootView;
    }
}

Метод onCreateView() получает LayoutInflater, ViewGroup и Bundle в качестве параметров. LayoutInflater — это компонент, который может создавать экземпляр View на основе XML-файлов макета. Как видите, в примере это действительно делается путем вызова layout.inflate(). Метод inflate() принимает три параметра: идентификатор XML-файла макета (внутри R.layout), родительскую ViewGroup, в которую нужно вставить представление фрагмента, и третье логическое значение, указывающее, является ли фрагмент Представление, увеличенное из XML-файла макета, должно быть вставлено в родительскую ViewGroup. В этом случае мы передадим false, потому что View будет присоединен к родительской ViewGroup в другом месте с помощью некоторого кода Android, который мы вызываем. Когда вы передаете false в качестве последнего параметра для inflate(), родительская ViewGroup по-прежнему используется для расчетов макета раздутого представления, поэтому вы не можете передать null в качестве родительской ViewGroup. Параметр ViewGroup функции onCreateView() является родительской ViewGroup, в которую нужно вставить представление фрагмента. Это ViewGroup внутри активности, которая будет «размещать» фрагмент. Параметр Bundle onCreateView() — это Bundle, в котором фрагмент может сохранять данные, как и в Activity.

Пример фрагмента Android

Пример кода фрагмента Android

MainActivity содержит два фрагмента: TextFragment и MenuFragment. Итак, давайте начнем с определения фрагментов в XML-макете activity_main.xml.

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:weightSum="1.0">

    <fragment
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        class="journaldev.com.fragments.fragments.MenuFragment"
        android:id="@+id/fragment"
        android:layout_weight="0.5"/>
    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="journaldev.com.fragments.fragments.TextFragment"
        android:id="@+id/fragment2"
        android:layout_weight="0.5"/>
</LinearLayout>

Как мы видим, файлы классов фрагментов, являющихся частью этой активности, определены как class=\journaldev.com.fragments.fragments.TextFragment. Классы фрагментов и их макеты определены, как показано во фрагментах ниже.

package journaldev.com.fragments.fragments;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import journaldev.com.fragments.R;
public class TextFragment extends Fragment {
    TextView text,vers;

    @Override

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

        View view = inflater.inflate(R.layout.text_fragment, container, false);
        text= (TextView) view.findViewById(R.id.AndroidOs);
        vers= (TextView)view.findViewById(R.id.Version);


        return view;

    }
    public void change(String txt, String txt1){
        text.setText(txt);
        vers.setText(txt1);

    }
}

text_fragment.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:gravity="center"
    android:background="#5ba4e5"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40px"
        android:textColor="#ffffff"
        android:layout_gravity="center"
        android:id="@+id/AndroidOs"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textColor="#ffffff"
        android:textSize="30px"
        android:id="@+id/Version"/>

</LinearLayout>

TextFragment состоит из текстовых представлений, содержащих имя и номер версии Android.

package journaldev.com.fragments.fragments;

import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import journaldev.com.fragments.R;
public class MenuFragment extends ListFragment {
    String[] AndroidOS = new String[] { "Cupcake","Donut","Eclair","Froyo","Gingerbread","Honeycomb","Ice Cream SandWich","Jelly Bean","KitKat" };
    String[] Version = new String[]{"1.5","1.6","2.0-2.1","2.2","2.3","3.0-3.2","4.0","4.1-4.3","4.4"};
    @Override

    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        View view =inflater.inflate(R.layout.list_fragment, container, false);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_list_item_1, AndroidOS);
        setListAdapter(adapter);

        return view;

    }
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        TextFragment txt = (TextFragment)getFragmentManager().findFragmentById(R.id.fragment2);
        txt.change(AndroidOS[position],"Version : "+Version[position]);
        getListView().setSelector(android.R.color.holo_blue_dark);
    }
}

list_fragment.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@android:id/list" />
</LinearLayout>

MenuFragment отображает ListView. Как мы видим здесь, макет ListView по умолчанию — это simple_list_item_1, в отличие от пользовательского макета, который мы создали для ListView в предыдущей статье. MainActivity вызывает setContentView из метода onCreate, вот и все. Фрагменты вызываются из файла xml. В качестве альтернативы мы можем добавить фрагменты из класса активности, используя FragmentManager, как показано во фрагменте ниже:

getFragmentManager()
                  .beginTransaction()
                  .add(R.id.fragmentParentViewGroup, new MyFragment())
                  .commit();

Здесь идентификатор fragmentParentViewGroup принадлежит FrameLayout, показанному ниже:

<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
             xmlns:tools="https://schemas.android.com/tools"
             android:id="@+id/fragmentParentViewGroup"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             tools:context=".MyActivity"
             tools:ignore="MergeRootFrame" />

Пример приложения Android Fragment

Скачать проект фрагмента Android