FragmentContainerView vs FrameLayout

Начиная с 2019 года Google рекомендует заменять контейнеры для фрагментов такие как <fragment> и <FrameLayout> на FragmentContainerView.

Может мне кто-то объяснить в чем принципиальная разница между этими контейнерами? И чем FragmentContainerView реально лучше?


Ответы (2 шт):

Автор решения: Sergei Buvaka

В общем порывшись достаточно на просторах интернета нашел несколько штук:

  • может быть использован как обычный контейнер в замену FrameLayout вместе с fragmentManager()

  • он может использоваться так же и в замену <fragment>:

    <androidx.fragment.app.FragmentContainerView
         android:id="@+id/fragmentContainer"
         class="com.example.YourFragment"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
    
  • в нем решена проблема Z координат exit анимаций фрагмента. Подробнее тут

  • хоть сам по себе FragmentContainerView наследуется от FrameLayout в него нельзя класть никаких других View. В противном случае словите Exception.

  • здесь мы можем указать параметр tag (опциональный) по которому в последствии мы можем вытянуть наш фрагмент методом FragmentManager.findFragmentByTag(tag):

    <androidx.fragment.app.FragmentContainerView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:tag="myFragment" />
    
  • animateLayoutChanges - если мы поставим его true то словим UnsupportedOperationException в любом андроиде после API level 18

Если у кого-то еще есть что дополнить буду рад.

→ Ссылка
Автор решения: Alex_Skvortsov

Поискав по сети я сумел найти немного информации на счет FragmentContainerView. Формально эта информация есть в официальной документации, но подана она скудно, внимание на этом аспекте не акцентировано. Лично я пропустил все самое важное при чтении документации :)

Итак, в чем плюсы FragmentContainerView в сравнении с FrameLayout:

  1. Позволяет задать начальный фрагмент через атрибуты xml (android:name="com.example.MyFragment" или class="com.example.MyFragment")
  2. Позволяет задать тэг начальному фрагменту прямо через верстку посредством атрибута android:tag="my_tag"
  3. Запрещает добавление каких-либо view помимо фрагментов (не самый большой плюс, но убирает возможность ошибиться случайно)
  4. По умолчанию отключена анимация транзакция для API > 17.

Именно 4 пункт является ключевым. Существует известный баг, заключается он в том, что невозможно адекватно кастомизировать одновременно анимацию открытия нового фрагмента и закрытия старого. Суть бага в том, что анимации запускаются одновременно, однако визуально сначала полностью исчезает старый фрагмент, а затем продолжается анимация открывающегося фрагмента (до этого он просто скрыт старым фрагментом). Выглядит не очень хорошо. В FragmentContainerView по умолчанию отключена механика, вызывавшая баг, кастомные анимации можно задавать так же, как и раньше через setCustomAnimations.

Если Вы не используете анимации для открытия / закрытия фрагментов и уверены, что не будете их использовать, то особых причин переезжать на FragmentContainerView нет. Анимации - единственное, что изменилось принципиально и что нельзя (очень трудно) починить своими силами.

Ну и все, что есть на этот счет в доках:

Layout animations and transitions are disabled for FragmentContainerView for APIs above 17. Otherwise, Animations should be done through FragmentTransaction.setCustomAnimations(int, int, int, int). If animateLayoutChanges is set to true or setLayoutTransition(LayoutTransition) is called directly an UnsupportedOperationException will be thrown.

Fragments using exit animations are drawn before all others for FragmentContainerView. This ensures that exiting Fragments do not appear on top of the view.

Шрифтом или как-то иначе это выделить, увы, не догадались.

→ Ссылка