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

3

182

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?

Jehol answered 25/6, 2013 at 11:50 Comment(2)
I'd like to see this support added as well.Judicial
This might be solvable some time in the future by the tools attribute. code.google.com/p/android/issues/detail?id=61652Anthropophagi
A
417

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.

Angelitaangell answered 16/9, 2016 at 20:36 Comment(4)
Does anyone know how to show the preview correctly when you add your custom view tag in another layout file? <com.yourpackage.yourcustomview id="@+id/my_cust_view" android:layout_width="match_parent" android:layout_height="match_parent"/>Multiplicand
See visual difference raw.githubusercontent.com/nisrulz/android-tips-tricks/develop/…Pozsony
Since you are using tools you could as well use tools:layout_height="match_parent"Zucchetto
The width and height tags seem to not (longer) be necessary, tested with Android Studio Bumblebee | 2021.1.1 Patch 2.Pera
A
67

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>
Anthropophagi answered 9/5, 2014 at 8:56 Comment(5)
Good news! Not very handy for compound components, because we need to add extra layout only for preview. But better than nothing.Jehol
Any ideas on something similar is supported in Eclipse?Smallminded
You can follow a ticket, reported by a google developer here : code.google.com/p/android/issues/detail?id=61652Ismaelisman
I set some attributes to the root view (in this case RelativeLayout) programmatically, like padding. Of course they're not applied in this helper layout (because you use a completely other view). The only solution was to use the whole custom view in the helper layout.Selfsupport
not outdated it could be used when you don't want generic viewingSerg
V
-6

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.

Visional answered 6/9, 2014 at 8:27 Comment(1)
This introduces an infinite recursion and the stack overflows when trying to preview, making the whole Android Studio hang forever.Bermuda

© 2022 - 2024 — McMap. All rights reserved.