Home » Android » Preview layout with merge root tag in Intellij IDEA/Android Studio

Preview layout with merge root tag in Intellij IDEA/Android Studio

Posted by: admin March 10, 2020 Leave a comment

Questions:

Let’s imagine we are developing compound component based on LinearLayout. So, we create class like this:

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

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

If we’ll use LinearLayout as a root of somelayout.xml, we’ll have extra view level, so we use merge tag:

<?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>

But in Preview tab in IDE merge always acts as FrameLayout, and we’ll see something like that:
Preview with merge

(It is Android Studio, Intellij IDEA is just the same, about Eclipse I don’t know)

Preview speed up developing layouts a lot, it’s sad lose such a great help even for some layouts. May be there is a way to specify, how Preview should interpret merge tag in particular layout?

How to&Answers:

There is a new parentTag tools attribute (added in Android Studio 2.2) that you can use to specify the layout type for a merge tag, which will make the layout render correctly in the layout editor preview.

So using your example:

<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>

Note: Both android:layout_width and android:layout_height must be specified in order for the layout to display properly in the editor.

Answer:

Edit: Outdated answer. See answer by starkej2.


Android Studio 0.5.8 added support for tools:showIn. By using it it is possible to preview < merge > layouts.

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

layout/layout_merge.xml with tools: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 with 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>

Answer:

Is also possible use custom class as parent instead of merge like

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

And then directly inflate this layout and cast result view to SomeView.
Android studio will directly check parent class of SomeView and handle preview like LinerLayout.
You can use onFinishInflate() method in the SomeView to bind views by findViewById().
Benefit of this solution is that you can put all layout definitions or style definition directly to the layout file, you can’t use method like setOrientation() in code.