Транзакції фрагментів використовуються для додавання, видалення, приєднання, від'єднання і заміни фрагментів в списку фрагментів. Вони лежать в основі механізму використання фрагментів для формування і модифікації екранів під час виконання. FragmentManager веде стек транзакцій, по якому ви можете переміщатися.
Метод FragmentManager.beginTransaction() створює і повертає екземпляр FragmentTransaction. Клас FragmentTransaction використовує динамічний інтерфейс — методи, настроюючі FragmentTransaction, повертають
FragmentTransaction замість void, що дозволяє об'єднувати їх виклики в ланцюжок. Таким чином, виділений код в лістингу 7.12 означає: «Створити нову транзакцію фрагмента, включити в неї одну операцію add, а потім закріпити».
Метод add(.) є основним змістом транзакції. Він отримує два параметри: ідентифікатор контейнерного представлення і нещодавно створений об'єкт CrimeFragment. Ідентифікатор контейнерного представлення вам має бути знаком: це ідентифікатор ресурсу елементу FrameLayout, визначеного у файлі activity _ crime.xml. Ідентифікатор контейнерного представлення виконує дві функції:
Він повідомляє FragmentManager, де в уявленні активності повинне знаходитися представлення фрагмента.
Він забезпечує однозначну ідентифікацію фрагмента в списку Fragment - Manager.
Коли вам потрібно буде отримати екземпляр CrimeFragment від FragmentManager, запросите його по ідентифікатору контейнерного представлення.
Лістинг 7.13. Отримання існуючого фрагмента по ідентифікатору контейнерного представлення(CrimeActivity.java)
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
if(fragment == null) {
fragment = new CrimeFragment(); fm.beginTransaction()
.add(R.id.fragmentContainer, fragment)
.commit();
}
Може здатися дивним, що FragmentManager ідентифікує CrimeFragment по ідентифікатору ресурсу FrameLayout. Проте ідентифікація UI- фрагмента по ідентифікатору ресурсу його контейнерного представлення вбудована в механізм
роботи FragmentManager.
Тепер ми можемо коротко описати код, доданий в лістинг 7.11, від початку до кінця.
Спочатку ми просимо у FragmentManager фрагмент з ідентифікатором контейнерного представлення R.id.fragmentContainer. Якщо цей фрагмент вже знаходиться в списку, FragmentManager повертає його.
Чому фрагмент може вже знаходитися в списку? Виклик CrimeActivity.onCre - ate(.) може бути виконаний у відповідь на відтворення об'єкту CrimeActivity після його знищення із-за повороту або звільнення пам'яті. При знищенні активності її екземпляр FragmentManager зберігає список фрагментів. При відтворенні активності новий екземпляр FragmentManager завантажує список і відтворює фрагменти, що зберігаються в нім, щоб все працювало, як раніше.
З іншого боку, якщо фрагменти із заданим ідентифікатором контейнерного представлення відсутні, значення fragment рівне null. В цьому випадку ми
створюємо новий екземпляр CrimeFragment і нову транзакцію, яка додає фрагмент в список.
Тепер CrimeActivity є хостом для CrimeFragment. Щоб переконатися в цьому, запустите додаток CriminalIntent. На екрані відображається представлення, визначене у файлі fragment _ crime.xml(мал. 7.17).
Мал. 7.17. CrimeActivity є хостом представлення CrimeFragment
Можливо, один віджет на екрані виглядає не таким вже великим досягненням для усієї роботи, виконаної в цій лабораторній роботі. Проте ми заклали міцний фундамент для серйозніших завдань, які нам доведеться вирішувати в додатку CriminalIntent.