Подтвердить что ты не робот

Почему дополнительный фрагмент FrameLayout создан для фрагментов?

При использовании просмотра иерархии, чтобы уменьшить иерархию, я заметил, что при каждом добавлении фрагмента (как в статическом "или" динамический "способ) фрагменты всегда завернуты в новый FrameLayout.

Вот пример:

Это мой макет :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="mainActivityRoot" >

<TextView
    android:id="@+id/hello_world"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

<fragment
    android:name="com.example.testfragments.MainFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/hello_world" />

</RelativeLayout>

И это расположение фрагмента:

<ProgressBar android:id="@+id/ProgressBar1" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:contentDescription="mainFragmentRoot"
android:layout_height="match_parent" />

Исходный код активности пуст, кроме setContentView, И исходный код фрагмента содержит только

@Override
public View onCreateView(...) {
    return inflater.inflate(R.layout.fragment_main, container, false);
}

Теперь,

Я бы ожидал увидеть PrograssBar непосредственно в иерархии корня активности, но вместо этого есть еще один FrameLayout, о котором я понятия не имею, откуда он. Здесь снят снимок, нарисовал дополнительный кадр в ЖЕЛТЫХ: Dump view hierarchy - yellow is bad

Итак, мои вопросы - откуда они взялись? и могу ли я избавиться от него? В моем реальном приложении эти дополнительные FrameLayouts создают очень глубокие иерархии, которые, вероятно, являются плохими для производительности.

Спасибо!

4b9b3361

Ответ 1

Похоже, вы используете библиотеку поддержки v4, и вы забыли поставить и id на свой фрагмент xml-тега:), поэтому:

, откуда оно взялось?

Он исходит из строки 888 FragmentManager, где вы можете увидеть это:

f.mView = NoSaveStateFrameLayout.wrap(f.mView);

Причиной этого является обратная совместимость и лучше объясняется в заголовке комментария NoSaveStateFrameLayout, который гласит:

/**
 * Pre-Honeycomb versions of the platform don't have {@link View#setSaveFromParentEnabled(boolean)},
 * so instead we insert this between the view and its parent.
 */

могу ли я избавиться от него?

Ну, я могу подумать о трех вариантах:

  • У вас может быть ваша собственная реализация FragmentManager на основе версии версии v4 для версии, в которой вы опускаете этот контейнер, но я думаю, что усилия по написанию/поддержанию этого кода не стоят, плюс я не думаю, что накладные расходы из-за того, что FrameLayout является гигантским, если у вас есть проблемы с производительностью, у вас, возможно, есть другие оптимизации View для выполнения помимо этого (скажем, написать пользовательский вид, который extends View -), или сказать переосмыслить ваш макет/фрагменты, чтобы уменьшить количество просмотров в иерархии в определенной точке.
  • Дождитесь появления новой версии библиотеки поддержки v4, которая выполнит 1. < - yup. Я ленивый человек: D, вам придется записывать ошибку, если ее еще нет (см. 3.), крутая часть этого, вы можете даже внести свой патч или кого-то еще.
  • Поддержка только платформ (или дождаться), когда библиотека поддержки v4 не нужна (дольше), в реализации уровня API 11+ FragmentManager не имеет этого вложенного ViewGroup (см. строка 861 из 11+ FragmentManager), на тех, у кого вы получите что-то вроде этого:

Look mom!, no nested <code>FrameLayout</code>!!1

Я бы не стал волноваться за тех, о которых я упоминал, есть другие оптимизации, которые вы можете инвестировать в это время;)