如何让RelativeLayout使用merge和include?

时间:2010-02-23 07:44:18

标签: android android-layout merge include android-relativelayout

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

我搜索了Android初学者小组和此网站,但未能找到任何有助于我解决问题的内容。

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

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

示例主要布局文件:

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

8 个答案:

答案 0 :(得分:211)

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

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

答案 1 :(得分:33)

请参阅下面更高度投票的答案。我的工作已经过时了


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

CommonsWare 建议将包装包装在一个唯一的父容器中,但这样做是为了协助寻址和解决问题。在贾斯汀中包含

的同名视图
  

每个人都必须拥有   独特的父容器,你会的   在该容器上调用findViewById()   (ViewGroup)而不是   活性。

事实上,你也必须这样做才能让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很好地附加到标题,但我认为这是幻觉,因为它只是垂直地在标题下方流动。我也尝试在页脚包含的正上方设置一个按钮,但它也是浮动和错误的

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

答案 2 :(得分:8)

男人,这已经过时了,但它似乎出现在搜索的顶部,所以我要发表评论。

我认为这里的诀窍是<merge>标记与<include>标记相结合实质上删除了该级别的任何类型的“父”视图组。那么,你究竟要求“布局_低于”其他人?没有人。在那个层面上没有任何观点。

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

答案 3 :(得分: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的唯一解决方案

答案 4 :(得分:1)

  

看起来像android:layout_ *属性   在include中使用时要忽略   标签和所有合并的布局都是   显示在彼此之上。

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

  

此外,如果有人能想到办法   我只有一个合并xml布局   文件而不是5   非常感谢。

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

  

我找不到办法做到这一点   因为我需要访问每个   合并布局文件中的项目   运行

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

如果您可以创建一个使用2个以上合并文件的示例项目,您可以在运行时证明其内容,请告诉我们。

答案 5 :(得分:1)

尝试:

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

答案 6 :(得分:0)

在我的情况下,我尝试包含的布局以<merge标记开头。当我将其更改为布局时,请说<RelativeLayout它有效。以下是插图。

WORKING

<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 :(得分:0)

我遇到了同样的问题,甚至定义了function sumDigits(num) { var numStr = num.toString() var numArr = numStr.split('').map(Number); function sumHelper(arr) { // Base case: if (arr.length === 1) { return arr[0]; } // Otherwise recurse (return last number plus the sum // of the remainder): return arr.pop() + sumHelper(arr); } // Then use that recursive helper: return sumHelper(numArr); } console.log(sumDigits(1234))layout_width它也没有用。 问题是我所包含的布局有标签,删除后,一切都像魅力一样。 我认为合并不是布局标签,因此,它无法接收定位和尺寸参数。由于您定义的所有内容都会转移到内部父布局,因此设置就会被丢弃。

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

在:

layout_height

工作:

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