How to get RelativeLayout working with merge and include?

我已经尝试了几天,使我的布局更有效,从使用嵌套的 LinearLayouts的几个层次转换为一个 RelativeLayout,遇到了一些问题,我还没有能够找到一个解决办法..。

我已经搜索了 Android 初学者小组和这个网站,没有找到任何可以帮助我解决这个问题的东西。

我在一个博客上读到,你可以将布局、合并和包含标签结合起来。所以我有一个带有 RelativeLayout根元素的主布局文件。其中有5个 include 标记,它们引用5个不同的 xml 布局文件,每个文件都有一个用于 root 的 merge 元素(除了 id 之外,所有的 merge 文件都是相同的)。

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

示例主要布局文件:

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

包含的示例合并文件:

<?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,将非常感谢。我找不到这样做的方法,因为我需要在运行时访问合并布局文件中的每个项目..。

50953 次浏览

似乎是: 包含中使用时要忽略的 标记和所有合并的布局都是 放在一起。

我的猜测是,您不能从布局规则中引用在 <include>元素上定义的 android:id属性,而只能引用“实际”小部件和容器上的属性。

还有,如果有人能想出一个办法 我只有一个合并 xml 布局 而不是5 greatly appreciated.

Simple: put them all in one file.

我找不到办法 因为我需要访问每一个 处的合并布局文件中的 runtime

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

如果您可以创建一个使用2 + 合并文件的示例项目,您可以在其中演示内容在运行时是 没有可访问的,请让我知道。

看看下面的投票结果,我的答案已经过时了


我可以解决 贾斯汀提出的一个问题: RelativeLayout 无法管理 include 的定位(至少在这个简单的例子中,在1.6仿真器上)

CommonsWare 建议将包含包装在一个唯一的父容器中,但这样做是为了帮助在 贾斯汀的中寻址和确定相同名称的视图的范围

每一个都必须有一个 唯一的父容器,并且您将 调用该容器上的 findViewById () (ViewGroup) ,而不是在 活动。

实际上,您使用 也必须这么做是为了让 RelativeLayout 按照预期的方式运行:

This works (页脚 is well positioned):

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

This does not (页脚 is floating at top of screen):

<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 附加到 标题,但我认为这是错觉,因为它只是垂直地流动在标题下面。我还试图设置一个按钮右上方的脚注包括,但它得到了所有浮动和错误的,太

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

Include 标签有一个问题

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

为了在 RelativeLayout 上进行定位,您需要在 include 文件中而不是在主布局文件中设置晒版参数。那边

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 _ lay.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 的解决方案

老兄,这是旧的,但它似乎出现在搜索顶部,所以我要评论。

我认为这里的诀窍在于,<merge>标记与 <include>标记的结合实际上删除了该级别的任何类型的“父”视图组。那么,到底是谁在要求别人去“晒图”呢?没有人。那个层次没有景观。

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

在我的示例中,我试图包含的布局从 <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">

我有同样的问题,甚至定义 layout_widthlayout_height也不起作用。 问题是,我包含的布局有标签,删除它们之后,一切都像魔法一样运作。 我认为 merge 不是一个布局标记,因此它不能接收定位和大小参数。因为您在其中定义的所有内容都被转移到内部父布局中,所以设置就被丢弃了。

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>

Working:

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

尝试:

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