在Intellij IDEA/Android Studio中使用合并根标签预览布局

181

让我们想象我们正在基于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标签:

如果我们将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>

但在IDE的预览选项卡中,合并操作始终作为FrameLayout,我们将看到类似这样的东西:Preview with merge

(这是Android Studio,Intellij IDEA也一样,至于Eclipse我不清楚)

预览大大加快了布局开发速度,失去这样一个极好的帮助甚至对某些布局来说都很遗憾。也许有一种方法可以指定预览应该如何解释特定布局中的merge标签?


1
我也希望看到这种支持被添加进来。 - Christopher Perry
这个问题可能会在未来通过工具属性得到解决。https://code.google.com/p/android/issues/detail?id=61652 - Jonas
3个回答

415

在Android Studio 2.2中新增了一个parentTag工具属性(详见此处),你可以使用它来指定merge标签的布局类型,这将使布局在布局编辑器预览中正确渲染。

因此,以您的示例为例:

<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_widthandroid:layout_height属性。


1
有人知道如何在另一个布局文件中添加自定义视图标签时正确显示预览吗? <com.yourpackage.yourcustomview id="@+id/my_cust_view" android:layout_width="match_parent" android:layout_height="match_parent"/> - Arst
1
查看视觉差异 https://raw.githubusercontent.com/nisrulz/android-tips-tricks/develop/img/mergetaginlayout.jpg - Zar E Ahmer
3
由于您正在使用工具,因此您可以使用tools:layout_height =“match_parent”。 - cutiko
完美!谢谢。+1 - Carson J.
宽度和高度标签似乎不再必要,已在Android Studio Bumblebee | 2021.1.1 Patch 2中进行了测试。 - Uwe

67

编辑:回答已过时。请参见starkej2的回答。


Android Studio 0.5.8增加了对tools:showIn的支持。通过使用它,可以预览布局。

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

具有tools:showIn属性的layout/layout_merge.xml:

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

使用include的layout/simple_relativelayout.xml:

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

14
好消息!对于复合组件来说不是很方便,因为我们需要添加额外的布局才能进行预览。但总比没有好。 - darja
有没有类似的东西在Eclipse中也被支持? - Toguard
3
你可以关注一张由谷歌开发人员在此处报告的问题:https://code.google.com/p/android/issues/detail?id=61652 - Neige
我在根视图(在这种情况下是RelativeLayout)中以编程方式设置了一些属性,例如填充。当然,在此辅助布局中它们不会被应用(因为您使用了完全不同的视图)。唯一的解决方案是在辅助布局中使用整个自定义视图。 - Felix Edelmann
不过时的,当您不想要通用查看时可以使用。 - amorenew

-6

也可以使用自定义类作为父类,而不是像合并一样。

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

然后直接填充此布局并将结果视图转换为SomeView。 Android Studio将直接检查SomeView的父类并处理预览,例如LinerLayout。 您可以在SomeView中使用onFinishInflate()方法通过findViewById()绑定视图。 这种解决方案的好处是,您可以直接将所有布局定义或样式定义放入布局文件中,无法在代码中使用setOrientation()等方法。


2
这会引入无限递归,当尝试预览时堆栈溢出,导致整个Android Studio永久挂起。 - mato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接