Предварительный просмотр макета с тегом merge root в Intellij IDEA/Android Studio


Давайте представим, что мы разрабатываем составной компонент на основе LinearLayout. Итак, мы создаем класс следующим образом:

public class SomeView extends LinearLayout {
    public SomeView(Context context, AttributeSet attrs) {
        super(context, attrs);

        setOrientation(LinearLayout.VERTICAL);
        View.inflate(context, R.layout.somelayout, this);
    }
}

Если мы будем использовать LinearLayout в качестве корня somelayout.xml, у нас будет дополнительный уровень представления, поэтому мы используем тег merge:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Some text"
        android:textSize="20sp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Some other text"/>
</merge>

Но на вкладке Preview в IDE merge всегда действует как FrameLayout, и мы увидим что-то вроде этого: Предварительный просмотр с помощью слияния

(это Android Studio, идея Intellij точно такая же, про Eclipse я не знаю)

Предварительный просмотр сильно ускоряет разработку макетов, это печально потерять такое большое подспорье даже для некоторых макетов. Может быть, есть способ указать, как Preview должен интерпретировать тег merge в конкретном макете?

3 109

3 ответа:

В Android Studio 2.2добавлен новый атрибут parentTag tools (), который можно использовать для указания типа макета для тега слияния, что позволит корректно отобразить макет в окне предварительного просмотра редактора макетов.

Итак, используя Ваш пример:

<merge 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"
    tools:parentTag="LinearLayout"
    tools:orientation="horizontal">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Some text"
        android:textSize="20sp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Some other text"/>
</merge>

Примечание : для корректного отображения макета в Редакторе необходимо указать как android:layout_width, так и android:layout_height.

Правка: устаревший ответ. Смотрите ответ starkej2.


Android Studio 0.5.8 добавлена поддержка инструментов: showIn. С его помощью можно просматривать макеты .

Http://tools.android.com/recent/androidstudio058released

Layout / layout_merge.xml с инструментами: showIn:

<merge xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:custom="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   tools:showIn="@layout/simple_relativelayout">

......

</merge>

Layout / simple_relativelayout.xml с include:

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

    <include layout="@layout/layout_merge"/>

</RelativeLayout>

Также возможно использовать пользовательский класс в качестве родителя вместо слияния, как

<com.mycompany.SomeView xmlns:android="http://schemas.android.com/apk/res/android">
...
</com.mycompany.SomeView>

, а затем непосредственно раздуть этот макет и привести представление результата к SomeView. Android studio будет напрямую проверять родительский класс SomeView и обрабатывать предварительный просмотр, как LinerLayout. Вы можете использовать onFinishInflate() метод в SomeView для привязки представлений к findViewById(). Преимущество этого решения заключается в том, что вы можете поместить все определения макета или определения стиля непосредственно в файл макета, вы не можете использовать метод, подобный setOrientation() в коде.