Статьи

Android Fragment Lifecycle — поддержка нескольких экранов

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

Другими словами, на рынке есть много смартфонов с различным разрешением экрана и различной плотностью экрана. Чтобы сделать ситуацию более сложной, если это возможно, есть не только смартфоны, но и планшеты. Всем понятно, что между этими двумя классами устройств существуют большие различия в размерах экрана. Хорошо, когда мы разрабатываем приложение, мы должны помнить, что оно может работать на разных устройствах и должно быть оптимизировано, чтобы пользовательский опыт был полностью удовлетворен. Это создает много проблем, потому что мы должны настроить приложение так, чтобы оно работало по-разному, когда оно работает на смартфоне или планшете. То, что сказано до сих пор, известно как поддержка нескольких экранов . В предыдущем посте ( Как поддерживать несколько экранов в Android ) я говорил о том, как поддерживать несколько экранов с помощью функций Android, таких как создание разных макетов и так далее. Это метод, который все еще можно использовать, но этого недостаточно.

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

Android_fragment_details

и когда пользователь нажимает на элемент
Android_fragment_list

в то время как в случае планшета мы хотим «использовать» весь экран устройства, чтобы показать детали рядом со списком элементов.

Android_fragment-tablet

Как видно из приведенного выше примера, мы хотели бы иметь способ объединить «действия», чтобы их можно было использовать одновременно или в последовательности, когда один вызывает другой. Мы хотим организовать макет экрана без переписывания кода. Это не может быть сделано только с использованием нескольких макетов, нам нужно что-то еще.

Фрагмент

С Android 3.0 была представлена ​​новая «концепция» под названием Fragment . Фрагмент — это фрагмент кода Android с его макетом, который можно упорядочить и объединить для получения разных макетов. Используя фрагменты, мы можем повторно использовать код и в то же время удовлетворить требования к размеру экрана устройства. Фрагмент не может жить сам по себе, но только внутри Деятельности, и этот может содержать несколько фрагментов. Важно отметить, что фрагменты можно комбинировать с другими элементами действия, чтобы вам не приходилось переписывать весь интерфейс действия. Таким образом, используя фрагмент, мы можем манипулировать приложением master-detail (показано выше) следующим образом:

на смартфоне

и когда он работает на планшете, мы имеем:

ФРАГМЕНТ ЖИЗНЬ

Теперь мы знаем, когда полезно использовать фрагменты , нам нужно знать, как они работают. Фрагмент живет только внутри Activity, которая действует как контейнер. Каждый фрагмент имеет свою собственную иерархию представления, которая может быть раздута, как мы обычно делаем. Жизненный цикл фрагмента является более сложным, чем жизненный цикл действия, потому что он имеет больше состояний. Эти состояния жизненного цикла показаны ниже:

Давайте двигаться сверху вниз. В самом начале жизни фрагмента вызывается метод onInflate . Мы должны заметить, что этот метод вызывается, только если мы определяем фрагмент непосредственно в нашем макете, используя тег < фрагмент >. В этом методе мы можем сохранить некоторые параметры конфигурации и некоторые атрибуты, определенные в файле макета XML. После этого вызывается onAttach . Этот метод вызывается, как только фрагмент «присоединяется» к «отцовскому» действию, и мы можем использовать этот метод, чтобы сохранить ссылку на это действие. После этого мы имеем на создание . Это один из самых важных шагов, наш фрагмент находится в процессе создания. Этот метод может использоваться для запуска некоторого потока для получения информации о данных, возможно, с удаленного сервера. OnCreateView — это метод, вызываемый, когда фрагмент должен создать свою иерархию представления. Во время этого метода мы будем раздувать наш макет внутри фрагмента, как, например, в виджете ListView. На этом этапе мы не можем быть уверены, что наша деятельность все еще создана, поэтому мы не можем рассчитывать на нее в какой-либо операции. Мы получаем уведомление, когда действие «отец» создано и готово в onActivityCreated . Отныне наша деятельность активна и создана, и мы можем использовать ее, когда нам нужно. Следующий шаг — метод onStart . Здесь мы делаем обычные вещи, как в действии onStart, на этом этапе наш фрагмент видим, но он все еще не взаимодействует с пользователем. Когда фрагмент готов взаимодействовать с пользователем, вызывается onResume . В конце этого этапа наш фрагмент запущен !!

Тогда может случиться, что действие приостановлено, и поэтому вызывается onPause действия . Ну и метод фрагмента onPause тоже вызывается. После этого может случиться так, что операционная система решит уничтожить наш фрагментный вид, и тогда вызывается onDestroyView . После этого, если система решает отклонить наш фрагмент, она вызывает метод onDestroy . Здесь мы должны освободить все активные соединения и так далее, потому что наш фрагмент близок к смерти. Даже если он находится на стадии уничтожения, он все равно привязан к активности отца. Последний шаг — отсоединение фрагмента от действия, и это происходит при вызове onDetach .

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

Как только мы узнаем жизненный цикл фрагмента, нам все равно нужно знать, как его создать и прикрепить к действию. Первое, что нам нужно знать, это то, что если мы хотим создать наш фрагмент, мы должны расширить android.app.Fragment . Итак, давайте предположим, что у нас есть фрагмент с именем Fragment1 , для его создания и определения мы имеем:

1
2
3
public class Fragment1 extends Fragment {
...
}

Как мы уже говорили, фрагмент существует только внутри Activity, поэтому нужно где-то его определить. У нас есть два варианта:

  • Определите его непосредственно внутри XML-файла макета
  • Определите заполнитель в XML-файле макета и динамически управляйте фрагментом непосредственно в нашей Деятельности

То, как мы определяем наш фрагмент, влияет на его жизненный цикл, потому что в первом случае вызывается onInflate, а во втором случае жизненный цикл начинается с метода onAttach.

Если мы определим фрагмент в XML, мы просто

1
2
3
4
<fragment android:id="@+id/f1"
              class="com.survivingwithandroid.fragment.Fragment1"
              android:layout_width="match_parent"
              android:layout_height="20dp"/>

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

Макет Frameset и фрагмент

Если мы определим наш фрагмент внутри XML-файла макета, у нас не будет большой свободы для динамического изменения фрагмента. Есть еще один способ, который мы можем использовать для достижения большей свободы: мы можем использовать < FrameLayout >. В файле макета XML мы имеем:

1
2
3
<FrameLayout android:id="@+id/fl1"
             android:layout_width="match_parent"
             android:layout_height="200dp"/>

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

01
02
03
04
05
06
07
08
09
10
11
12
public class MainActivity extends Activity {
 
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 
    Fragment2 f2 = new Fragment2();
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.fl1, f2);
    ft.commit();
}

Мы поговорим подробнее о FragmentTransaction и так далее в следующих постах.

Ссылка: Android Fragment Lifecycle — поддержка нескольких экранов от нашего партнера JCG Франческо Аццолы в блоге Surviving с Android .