2014-01-31 4 views
16

У меня есть FrameLayout, который содержит TextView и два LinearLayout S:Предупреждение: Это <FrameLayout> может быть заменен <merge> тегом

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 


    ... a textview and 2 linearlayouts 


</FrameLayout> 

После запуска Android Lint, я получаю это предупреждение: This <FrameLayout> can be replaced with a <merge> tag.

Почему существует ли это предупреждение? Что я могу сделать, чтобы исправить это (кроме игнорирования)?

+2

В качестве примечания стороны: «Как правило, FrameLayout следует использовать для хранения одного дочернего представления» (из документов) –

ответ

23

Чтобы понять это, вам нужно понять, как раздуты и размещены макеты.

Скажем, например, у вас есть активность, и это макет xml, который вы используете. Вот как выглядит макет действия перед тем, как вы поместите свой файл макета.

<FrameLayout // This is the window 
    ... 
    <FrameLayout> // This is activity 
    </FrameLayout> 
</FrameLayout> 

В зависимости от устройства/ОС может быть несколько других уровней.

Теперь, когда вы раздуваете свой файл макета и вставляете его, так оно и будет выглядеть.

<FrameLayout // This is the window 
    ... 
    <FrameLayout> // This is activity 
     // Your layout below 
     <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" > 
       ... a textview and 2 linearlayouts 
     </FrameLayout> 
    </FrameLayout> 
</FrameLayout> 

Вы видите FrameLayout внутри FrameLayout? Это избыточно, потому что это не добавляет большого значения. Чтобы оптимизировать, вы можете заменить FrameLayout на < merge>. Если вы используете, то это будет выглядеть.

<FrameLayout // This is the window 
    ... 
    <FrameLayout // This is activity 
     // Your layout below 
       ... a textview and 2 linearlayouts 
    </FrameLayout> 
</FrameLayout> 

Обратите внимание, что дополнительных кадров FrameLayout нет. Вместо этого он просто сливается с FrameLayout активности. Всякий раз, когда вы можете, вы должны использовать < merge>. Это относится не только к FrameLayouts. Вы можете прочитать больше об этом здесь. http://developer.android.com/training/improving-layouts/reusing-layouts.html#Merge

Надеюсь, это поможет.

+0

Вам может понадобиться тэг Fragment, если к макету должен обращаться идентификатор, например, когда он должен использоваться как контейнер для фрагментов. – user1841702

7

Вы используете это как основное расположение своей деятельности? Если да, то вы можете заменить его с тегом слияния, как это:

<merge xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    ... a textview and 2 linearlayouts 


</merge> 

В setContentView, Android будет принимать детей из слияния тега и непосредственно вставить их в FrameLayout с @android:id/content. Изучите оба подхода (FrameLayout vs merge) с HierarachyViewer, чтобы увидеть разницу.

+0

chiuki, вы можете объяснить, что означает '@android: id/content'? +1 за предложение «Иерархический просмотрщик»! –

+0

'@android: id/content' является идентификатором корня' FrameLayout', где 'setContentView' помещает ваш макет. – chiuki

1

См. Сообщение this Романом Гаем для получения дополнительной информации. Он сообщает вам, почему предлагается вариант слияния.