Давайте рассмотрим один из лейаутов в QuoteFragment, то, как он создает свой пользовательский интерфейс. Имеется класс QuoteFragment и его метод onCreateView.

Этот метод вызывает метод inflate класса LayoutInflater, передавая файл лейаута (quote_fragment.xml) в качестве параметра. Это работает подобно тому, что происходит в setContentView.
Вы можете также добавить фрагменты в Activity без хардкодинга фрагментов в файле лейаута Activity. Для этого, в то время как Activity работает, надо сделать четыре вещи. Первое – получить ссылку на FragmentManager. Второе – начать FragmentTransaction. Третье – добавить фрагмент в Activity. И четвертое – зафиксировать (commit) FragmentTransaction.
Давайте откроем QuoteViewerActivity и посмотрим, как она обрабатывает свой лейаут (layout).

В onCreate есть вызов setContentView со значением параметра R.layout.main. Поэтому давайте посмотрим в каталоге res/layout файл main.xml.
Этот лейаут состоит из LinearLayout с двумя подразделами. Но вместо фрагментов на сей раз подразделы – это FrameLayout. FrameLayout должен зарезервировать некоторое пространство в пользовательском интерфейсе, и мы заполним это пространство позже, когда будем добавлять фрагменты в эту Activity.

Теперь давайте вернемся к методу onCreate в QuoteViewerActivity и пройдем по тем четырем шагам, добавляя фрагменты в Activity. Во-первых, получаем ссылку на FragmentManager. Затем вызываем метод beginTransaction. В результате получим FragmentTransaction. Затем вызываем метод add, передавая ID FrameLayout во фрагмент, который будет содержать этот FrameLayout. Это надо сделать и для TitleFragment, и для QuoteFragment. И, наконец, вызовем метод commit, чтобы зафиксировать все изменения.


Теперь мы знаем как добавить фрагменты в Activity программно. Но в нашем примере это не имело такого большого значения в том смысле, что даже при том, что мы добавили фрагменты программно, их расположение (лейаут) было статично. Всегда есть только две панели, и это никогда не изменяется.
И один из плюсов способности добавлять фрагменты на лету – то, что она позволяет динамически изменять пользовательский интерфейс во время работы программы. И если делать это правильно, это позволит рационально использовать драгоценное экранное пространство.
Рассмотрим приложение «FragmentProgrammaticLayout», которое демонстрирует некоторые разновидности динамических пользовательских интерфейсов. Приложение иногда будет показывать единственный фрагмент, а иногда – несколько фрагментов.
Сразу после запуска мы видим только TitleFragment с заголовками пьес. Если кликнуть по заголовку, вы увидите справа уже знакомую цитату из Гамлета. В этой точке приложение выводит на экран два фрагмента. Если теперь нажать кнопку "Назад", вы увидите, что мы вернулись к отображению единственного фрагмента.
Теперь рассмотрим код. На сей раз в начале мы добавим только TitleFragment, а фрагмент с цитатами будем добавлять только, если пользователь кликнет по заголовку. Предположим, пользователь действительно кликает по заголовку. Тогда будет вызван метод onListSelection. Рассмотрим этот метод.

Во-первых, мы проверяем, был ли фрагмент с цитатами уже добавлен в layout. И, если нет, то мы добавим его, запуская другой FragmentTransaction.
Далее мы собираемся добавить эту транзакцию в стек задачи (Task backstack) для того, чтобы пользователь вернулся к тому состоянию экрана, который был прежде, до добавления нового фрагмента, когда он нажмет кнопку "Назад". И это надо сделать, потому что по умолчанию в стеке задач изменения фрагментов не отслеживаются.
В конце добавляем вызов FragmentManager.executePendingTransactions. Это вынуждает транзакцию выполниться сразу, а не тогда, когда система посчитает удобным это сделать, и нам пришлось бы ждать, пока обновится экран.
В главе об Activity мы говорили о том, как Activity могут обрабатывать изменения конфигурации вручную используя методы, такие как onRetainNonConfigurationInstance и getLastNonConfigurationInstance.
При изменении конфигурации устройства Android по умолчанию уничтожит Activity и воссоздаст ее. Однако, если вызвать метод setRetainInstance во фрагменте, передав в качестве параметра true, то когда произойдут изменения конфигурации, Android уничтожит Activity, но не уничтожит фрагменты, которые она содержит. Android сохранит состояние фрагмента, отсоединив фрагмент от Activity. И, кроме того, Android не уничтожит этот фрагмент и не воссоздаст его позже, когда Activity будет воссоздана. В результате фрагмент не получит вызова своих методов onDestroy и onCreate.
Читать дальше
Конец ознакомительного отрывка
Купить книгу