首页 文章

如何让RelativeLayout使用merge和include?

提问于
浏览
113

我已经尝试了几天,通过使用几个级别的嵌套 LinearLayouts 转换为一个 RelativeLayout 来使我的布局更有效,并且遇到了一些我无法找到解决方法的问题......

我搜索了Android初学者小组和这个网站,但却找不到任何可以帮我解决问题的方法 .

我在其中一个博客上看到,您可以将布局与合并和包含标签结合起来 . 所以我有一个带有 RelativeLayout 根元素的主布局文件 . 在其中我有5个包含标签,它们引用了5个不同的xml布局文件,每个文件都有一个根的合并元素(我的所有合并文件都是相同的,除了它们中的ID) .

我遇到了两个问题,我将在发布布局代码的简化版后解释:

Sample Main Layout File:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/translucent_gray" >

    <include 
        android:id="@+id/running_gallery_layout_id"
        layout="@layout/running_gallery_layout" />

    <include 
        android:id="@+id/recent_gallery_layout_id" 
        layout="@layout/recent_gallery_layout"
        android:layout_below="@id/running_gallery_layout_id" />

    <include
        android:id="@+id/service_gallery_layout_id"
        layout="@layout/service_gallery_layout"
        android:layout_below="@id/recent_gallery_layout_id" />

    <include
        android:id="@+id/process_gallery_layout_id"
        layout="@layout/process_gallery_layout"
        android:layout_below="@id/service_gallery_layout_id" />

</RelativeLayout>

Sample included merge file:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <TextView 
        style="@style/TitleText"
        android:id="@+id/service_gallery_title_text_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:text="@string/service_title" />

    <Gallery
        android:id="@+id/service_gallery_id"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_below="@id/service_gallery_title_text_id" />

    <TextView 
        style="@style/SubTitleText"
        android:id="@+id/service_gallery_current_text_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/service_gallery_title_text_id"
        android:layout_above="@id/service_gallery_id" />
</merge>

我遇到两个问题:

1)在include标记中使用时,似乎忽略了 android:layout_* 属性,并且所有合并的布局都显示在彼此之上 . 根据这篇文章(http://developer.android.com/resources/articles/layout-tricks-reuse.html)“任何 android:layout_* 属性都可以与 <include /> 标签一起使用”

2)由于我无法正常工作,我决定尝试将 android:layout_below 属性添加到每个合并布局文件中的第一个 TextView 项,这意味着每个合并文件将引用另一个合并布局文件中的id ...最多部分这实际上工作,我的布局看起来很好 . 但是,我收到一个 android:layout_below 属性的错误,说它无法找到我指定的ID ...我有两次和三次检查ID以确保它们是正确的 . 最奇怪的部分是我使用 AutoFill 功能将id放在属性中 .

如果有人有任何建议或解决方法,我将非常乐意尝试一下 . 此外,如果有人能想到一种方法让我只有一个合并xml布局文件而不是5,将非常感激 . 我无法找到一种方法,因为我需要在运行时访问合并布局文件中的每个项目...

7 回答

  • 210

    include标记存在问题 . 检查:https://issuetracker.google.com/issues/36908001

    要修复它,请确保在包含时覆盖BOTH layout_widthlayout_height ,否则将忽略所有内容 .

  • 1

    See the more highly voted answer below. Mine is woefully outdated


    我可以解决一个问题 Justin 引发:RelativeLayout无法管理包含的定位(至少在这个简单的情况下,在1.6模拟器上)

    CommonsWare 建议将包装包装在唯一的父容器中,但这样做是为了帮助在 Justin's 中包含寻址和范围相同的视图

    每个都必须有一个唯一的父容器,你可以在该容器(ViewGroup)上而不是在Activity上调用findViewById() .

    实际上,您还必须执行此操作才能使RelativeLayout按预期运行:

    这工作(页脚定位良好):

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent" android:layout_height="fill_parent">
        <include android:id="@+id/header" layout="@layout/header"
            android:layout_alignParentTop="true" />
        <WebView android:id="@+id/webView" android:layout_below="@id/header"
            android:background="#77CC0000" android:layout_height="wrap_content"
            android:layout_width="fill_parent" android:focusable="false" />
        <LinearLayout android:layout_alignParentBottom="true"
            android:layout_height="wrap_content" android:layout_width="fill_parent">
            <include android:id="@+id/footer" layout="@layout/footer" />
        </LinearLayout>
    </RelativeLayout>
    

    这不(页脚浮动在屏幕顶部):

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent" android:layout_height="fill_parent">
        <include android:id="@+id/header" layout="@layout/header"
            android:layout_alignParentTop="true" />
        <WebView android:id="@+id/webView" android:layout_below="@id/header"
            android:background="#77CC0000" android:layout_height="wrap_content"
            android:layout_width="fill_parent" android:focusable="false" />
        <include android:id="@+id/footer" layout="@layout/footer"
            android:layout_alignParentBottom="true" />
    </RelativeLayout>
    

    裸脚注包括不会对齐父母的底部,没有周围的LinearLayout ..我不会称之为预期的行为 .

    此外,WebView似乎通过ID很好地附加到 Headers ,但我认为这是幻觉,因为它只是垂直地在 Headers 下方流动 . 我也尝试在页脚包含的正上方设置一个按钮,但它也有浮动和错误

    RelativeLayout在1.5中有更多问题,但我仍然喜欢它:)

  • 0

    男人,这是旧的,但它似乎出现在搜索的顶部,所以我要发表评论 .

    我认为这里的诀窍是 <merge> 标签与 <include> 标签结合在一起基本上删除了该级别的任何类型的"parent"视图组 . 那么,你究竟是谁要求"layout_below"其他人?没有人 . 在那个级别没有观点 .

    <merge> 标记获取子视图并将它们直接弹出到 <include> 标记的父级中 . 因此,您必须要求您所包含的布局中的孩子相应地自我锚定 .

  • 4

    要在RelativeLayout上进行定位,您需要在include文件中设置layout_ *参数,而不是在主布局文件中 . 那样

    main_layout.xml

    <RelativeLayout
      android:id="@+id/header"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content">
       ....
    </RelativeLayout>
    
    <RelativeLayout 
      android:id="@+id/footer"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true">
        .....
    </RelativeLayout>
    
    <include layout="@layout/content_layout" />
    

    content_layout.xml

    <merge xmlns:android="http://schemas.android.com/apk/res/android">
    <RelativeLayout
        android:id="@+id/content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@id/footer"
        android:layout_below="@id/header" >
    
        ....
    </RelativeLayout>
    </merge>
    

    这显然不是我们开发人员想要的,但它是我发现避免重复xml的唯一解决方案

  • 32

    当android时,android:layout_ *属性似乎被忽略了在include标记中使用,并且所有合并的布局都显示在彼此之上 .

    我的猜测是,你无法从布局规则中引用在 <include> 元素上定义的 android:id 属性,只能在"real"小部件和容器上引用它们 .

    此外,如果有人能想到一种方法让我只有一个合并xml布局文件而不是5,将非常感激 .

    简单:将它们全部放在一个文件中 .

    我找不到办法,因为我需要在运行时访问合并布局文件中的每个项目

    无论您有一个 <include> 元素还是1,000个元素,都应该可以在运行时访问所有内容 . 一个例外是如果你有重复的 android:id 属性 - 你需要正确地调整你的 findViewById() 调用以获得正确的属性,就像从ListView行获取小部件时一样 .

    如果您可以创建一个使用2个合并文件的示例项目,您可以在其中演示在运行时无法访问这些内容,请告诉我们 .

  • 0

    在我的例子中,我试图包含的布局以 <merge 标签开头 . 当我把它改成布局时,说 <RelativeLayout 就可以了 . 下面是插图 .

    工作

    <RelativeLayout xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android"
        tools:showIn="@layout/activity_home">
    

    不工作

    <merge xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android"
        tools:showIn="@layout/activity_home">
    
  • 7

    我有同样的问题,甚至定义 layout_widthlayout_height 它没有用 . 问题是我所包含的布局有标签,删除后,一切都像魅力一样 . 我认为合并不是布局标签,因此,它无法接收定位和尺寸参数 . 由于您定义的所有内容都转移到内部父布局,因此设置只是丢弃 .

    TL:DR:只需删除标签,将xmlns定义移动到一个真实的布局视图,你应该是好的 .

    之前:

    <merge
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <...ui.component.BorderCardView
            android:layout_width="112dp"
            android:layout_height="32dp"
            app:cardCornerRadius="4dp"
            app:cardUseCompatPadding="true">
    
            <ImageView
                android:layout_width="16dp"
                android:layout_height="16dp"
                android:src="@drawable/ic_logout"
                android:tint="@color/divider" />
    
        </...ui.component.BorderCardView>
    </merge>
    

    工作:

    <...ui.component.BorderCardView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="112dp"
        android:layout_height="32dp"
        app:cardCornerRadius="4dp"
        app:cardUseCompatPadding="true">
    
        <ImageView
            android:layout_width="16dp"
            android:layout_height="16dp"
            android:src="@drawable/ic_logout"
            android:tint="@color/divider" />
    
    </...ui.component.BorderCardView>
    

相关问题