Почему дополнительный фрагмент 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, о котором я понятия не имею, откуда он. Вот скриншот, нарисовал дополнительную рамку в ЖЕЛТЫХ: Иерархия представления дампа - желтый - плохой

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

Благодаря!

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

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

откуда это?

Он исходит из строки 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. */ 

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

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

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

Посмотрите мама !, нет вложенных <code> FrameLayout </ code> !! 1

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