Android 如何让RelativeLayout 与合并和包含一起工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2316465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get RelativeLayout working with merge and include?
提问by Justin
I have been trying for a few days now to make my layouts more efficient by converting from using several levels of nested LinearLayouts
to one RelativeLayout
and have come across a few problems that I haven not been able to find a workaround for...
几天来,我一直在尝试通过从使用多个嵌套级别转换LinearLayouts
为一个级别来使我的布局更高效,RelativeLayout
并且遇到了一些我无法找到解决方法的问题......
I have searched the Android beginners group and this site and have not been able to find anything that would help me solve the problem.
我已经搜索了 Android 初学者组和这个网站,但没有找到任何可以帮助我解决问题的内容。
I read on one of the blogs that you can combine layouts with merge and include tags. So what I have is a main layout file with a RelativeLayout
root element. Inside of that I have 5 include tags that reference 5 different xml layout files that each have a merge element for the root (all of my merge files are the same except for the ids in them).
我在其中一篇博客上读到,您可以将布局与合并和包含标签结合起来。所以我拥有的是一个带有RelativeLayout
根元素的主布局文件。其中,我有 5 个 include 标签,它们引用了 5 个不同的 xml 布局文件,每个文件都有一个用于根的合并元素(我的所有合并文件都相同,除了其中的 id)。
I am running into two problems, which I will explain after posting a simplified version of my layout code:
我遇到了两个问题,我将在发布我的布局代码的简化版本后解释:
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>
I am running into two problems:
我遇到了两个问题:
1) The android:layout_*
attributes seem to be ignored when used in the include tag and all of the merged layouts are displayed on top of each other. According to this post (http://developer.android.com/resources/articles/layout-tricks-reuse.html) "any android:layout_*
attribute can be used with the <include />
tag"
1)android:layout_*
属性在包含标签中使用时似乎被忽略,所有合并的布局都显示在彼此的顶部。根据这篇文章(http://developer.android.com/resources/articles/layout-tricks-reuse.html)“任何android:layout_*
属性都可以与<include />
标签一起使用”
2) Since I couldn't get this working I decided to try adding an android:layout_below
attribute to the first TextView
item in each merge layout file, meaning that each merge file would be referencing an id from another merge layout file... For the most part this actually worked and my layout looks fine. However, I get an error on one of the android:layout_below
attributes saying that it can't find the id I specified... I have double and triple checked the ids to make sure they were correct. The weirdest part is that I used the AutoFill
feature to put the id in the attribute in the first place.
2)由于我无法使其正常工作,我决定尝试向每个合并布局文件中android:layout_below
的第一TextView
项添加一个属性,这意味着每个合并文件都将引用另一个合并布局文件中的 id ......在大多数情况下,这实际工作,我的布局看起来不错。但是,我在其中一个android:layout_below
属性上收到错误消息,说它找不到我指定的 id ……我对这些 id 进行了两次和三次检查以确保它们是正确的。最奇怪的部分是我首先使用该AutoFill
功能将 id 放在属性中。
If anyone has any suggestions or workarounds I will be more than happy to try them out. Also, if anyone can think of a way for me to just have one merge xml layout file instead of 5 that would be greatly appreciated. I couldn't find a way to do that because I need to have access to each item in the merge layout files at runtime...
如果有人有任何建议或解决方法,我将非常乐意尝试。另外,如果有人能想出一种方法让我只有一个合并 xml 布局文件而不是 5 个,那将不胜感激。我找不到办法做到这一点,因为我需要在运行时访问合并布局文件中的每个项目......
回答by Macarse
There is an issue with the include tag. Check: https://issuetracker.google.com/issues/36908001
include 标签有问题。检查:https: //issuetracker.google.com/issues/36908001
To fix it, make sure you overwrite BOTH layout_width
and layout_height
when including, otherwise everything will be ignored.
要修复它,请确保在包含时覆盖 BOTHlayout_width
和layout_height
,否则所有内容都将被忽略。
回答by alienjazzcat
See the more highly voted answer below. Mine is woefully outdated
请参阅下面投票率更高的答案。我的已经过时了
i can address one issue Justinraised: inability of RelativeLayout to manage positioning of an include (at least in this simple case, on a 1.6 emulator)
我可以解决Justin提出的一个问题:RelativeLayout 无法管理包含的定位(至少在这个简单的情况下,在 1.6 模拟器上)
CommonsWaresuggests wrapping the includes in a unique parent container, but does so in order to assist addressing & scoping identically named Views within Justin'sincludes
CommonsWare建议将包含的包含在一个唯一的父容器中,但这样做是为了帮助在Justin 的包含中处理和定义同名视图
Each would have to have a unique parent container, and you would call findViewById() on that container (ViewGroup) rather than on the Activity.
每个都必须有一个唯一的父容器,您可以在该容器 (ViewGroup) 上而不是在 Activity 上调用 findViewById()。
In fact, you also must do itin order to get RelativeLayout to behave as expected:
事实上,您还必须这样做才能使 RelativeLayout 像预期的那样工作:
This works (footeris 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 (footeris 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>
The bare footerinclude will not align to bottom of parent, without the surrounding LinearLayout.. I wouldn't call this expected behavior.
如果没有周围的 LinearLayout,裸页脚包括不会与父级底部对齐。我不会称这种行为为预期行为。
Additionally, the WebView appears to attach itself nicely to the headerby ID, but I believe this to be illusion, due to it simply flowing below the header vertically. I also tried to set a button right above the footer include, but it got all floaty and wrong, too
此外,WebView 似乎通过 ID很好地将自己附加到标题上,但我认为这是错觉,因为它只是在标题下方垂直流动。我还尝试在页脚包含的正上方设置一个按钮,但它也变得浮动和错误
RelativeLayout had more problems in 1.5, but i still like it :)
RelativeLayout 在 1.5 中有更多问题,但我仍然喜欢它 :)
回答by Plantage
Man, this is old, but it seems to come up at the top of searches, so I'm going to comment.
伙计,这是旧的,但它似乎出现在搜索的顶部,所以我要发表评论。
I think the trick here is that the <merge>
tag combined with the <include>
tag essentially remove any sort of "parent" view group at that level. So then, who exactly are you asking to "layout_below" someone else? No one. There is no view at that level.
我认为这里的技巧是<merge>
标签与标签的结合<include>
基本上删除了该级别的任何类型的“父”视图组。那么,你到底在要求谁“布局_低于”其他人?没有人。没有那个级别的观点。
The <merge>
tag takes the child views and pops them right into the parent of the <include>
tag. You must therefore ask the children in the layout you're including to anchor themselves accordingly.
该<merge>
标签获取子视图并将它们直接弹出到<include>
标签的父视图中。因此,您必须要求您所包含的布局中的孩子相应地锚定自己。
回答by Maragues
For positioning to work on RelativeLayout you need to set the layout_* parameters in the include file, not in the main layout file. That way
为了定位在 RelativeLayout 上工作,您需要在包含文件中设置 layout_* 参数,而不是在主布局文件中。那样
main_layout.xml
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
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>
This is obviously not what us developers want, but it's the only solution I've found to avoid duplicating xml
这显然不是我们开发人员想要的,但这是我找到的避免重复 xml 的唯一解决方案
回答by CommonsWare
The android:layout_* attributes seem to be ignored when used in the include tag and all of the merged layouts are displayed on top of each other.
android:layout_* 属性在包含标签中使用时似乎被忽略,所有合并的布局都显示在彼此的顶部。
My guess is that you cannot reference, from layout rules, android:id
attributes that are defined on <include>
elements, only ones that are on "real" widgets and containers.
我的猜测是,您不能从布局规则中引用元素android:id
上定义的属性<include>
,只能引用“真实”小部件和容器上的属性。
Also, if anyone can think of a way for me to just have one merge xml layout file instead of 5 that would be greatly appreciated.
另外,如果有人能想出一种方法让我只有一个合并 xml 布局文件而不是 5 个,那将不胜感激。
Simple: put them all in one file.
简单:将它们全部放在一个文件中。
I couldn't find a way to do that because I need to have access to each item in the merge layout files at runtime
我找不到这样做的方法,因为我需要在运行时访问合并布局文件中的每个项目
Whether you have one <include>
element or 1,000, all of the contents should be accessible at runtime. One exception is if you have duplicated android:id
attributes -- you would need to properly scope your findViewById()
calls to get the right one, just like you have to when getting widgets from a ListView row.
无论您有一个<include>
元素还是 1,000个元素,所有内容都应该在运行时可以访问。一个例外是,如果您有重复的android:id
属性——您需要适当地确定您的findViewById()
调用范围以获得正确的调用,就像从 ListView 行获取小部件时必须这样做一样。
If you can create a sample project that uses 2+ merge files where you can demonstrate that the contents are notaccessible at runtime, let me know.
如果您可以创建一个使用 2 个以上合并文件的示例项目,您可以在其中证明在运行时无法访问内容,请告诉我。
回答by zahra salmaninejad
try :
尝试 :
<RelativeLayout xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:showIn="@layout/activity_home">
回答by Rohit Mandiwal
In my case, the layout which I was trying to include starts with <merge
tag. When I changed it to a layout, say <RelativeLayout
it worked. Below is the illustration.
就我而言,我试图包含的布局以<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">
NOT WORKING
不工作
<merge xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:showIn="@layout/activity_home">
回答by silvio.pereira
I had the same problem and even defining layout_width
and layout_height
it didn't work.
The problem was that the layout I was including had tags and after removing them, everything worked like a charm.
I suppose that merge is not a layout tag and because of that, it cannot receive positioning and size parameters. Since everything you define in is transferred to the inner parent layout, the settings just were throw away.
我有同样的问题,甚至定义layout_width
,layout_height
它没有用。问题是我包含的布局有标签,删除它们后,一切都像魅力一样。我想合并不是布局标签,因此,它无法接收定位和大小参数。由于您定义的所有内容都传输到内部父布局,因此设置被丢弃了。
TL:DR: Just remove the tags, move the xmlns definitions to a real layout viewholder and you should be good.
TL:DR:只需删除标签,将 xmlns 定义移动到真正的布局视图中,您应该会很好。
Before:
前:
<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>