Android XML Layout的'include'标签确实有效吗?


84

在我的Android布局文件中使用<include>时,我无法覆盖属性。当我搜索错误时,发现拒绝的问题2863

“ include标记已损坏(覆盖的布局参数永远无效)”

由于Romain指出这在测试套件及其示例中有效,因此我一定做错了。

我的项目是这样组织的:

res/layout
  buttons.xml

res/layout-land
  receipt.xml

res/layout-port
  receipt.xml

button.xml包含以下内容:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

  <Button .../>

  <Button .../>
</LinearLayout>

人像和风景的receive.xml文件看起来像:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

  ...

  <!-- Overridden attributes never work. Nor do attributes like
       the red background, which is specified here. -->
  <include
      android:id="@+id/buttons_override"
      android:background="#ff0000"
      android:layout_width="fill_parent"
      layout="@layout/buttons"/>

</LinearLayout>

我想念什么?


当您尝试以不支持的方式使用include时,Android开发人员工具会提到此问题。
ThomasW

Answers:


132

我刚发现问题。首先,您只能覆盖layout_ *属性,因此背景将无法使用。这是有据可查的行为,而对我而言只是一个疏忽。

真正的问题在LayoutInflater.java中找到:

// We try to load the layout params set in the <include /> tag. If
// they don't exist, we will rely on the layout params set in the
// included XML file.
// During a layoutparams generation, a runtime exception is thrown
// if either layout_width or layout_height is missing. We catch
// this exception and set localParams accordingly: true means we
// successfully loaded layout params from the <include /> tag,
// false means we need to rely on the included layout params.
ViewGroup.LayoutParams params = null;
try {
   params = group.generateLayoutParams(attrs);
} catch (RuntimeException e) {
   params = group.generateLayoutParams(childAttrs);
} finally {
   if (params != null) {
     view.setLayoutParams(params);
   }
}

如果<包括>标签不包括layout_width和layout_height的RuntimeException的发生,并默默处理,没有任何日志语句均匀。

解决方案是,如果要覆盖任何layout_ *属性,则在使用<include>标记时始终同时包含layout_width和layout_height。

我的示例应更改为:

<include
      android:id="@+id/buttons_override"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      layout="@layout/buttons"/>

33
这是荒唐的。我从来没有能够做到这一点,我什至看到文档中提到如果要覆盖尺寸(高度和宽度)都需要高度和宽度。但是,我要覆盖的只是保证金,这实际上不是一个维度。当我要更改的只是layout_marginRight时,为什么要同时指定这两个或什至任何一个?Grrr,Android,有时您会让我感到非常沮丧。
Artem Russakovskii 2010年

1
如果您不同时覆盖height和width属性,则仅供参考,FYI Android Lint会给您一个错误(忽略布局参数layout_height,除非在<include>标签上也指定了layout_width)
二进制

10

我提交了一个增强请求,以允许覆盖所有包含的属性:

假设我有两个相同的布局,而不是TextView字段的值 。目前,我要么在运行时修改布局,要么复制XML。

例如,将两个值为“ hello”和“ world”的参数传递给layout1:

<include layout="@layout/layout1a" params="textView=hello|editText=world" />

layout1a.xml:

<merge><TextView text="@param/textView"><EditText hint="@param/editText"></merge>

替代实现将破坏封装,并允许include语句覆盖以下值:

<include layout="@layout/layout1b" overrides="@id/textView.text=hello|@id/editText.hint=world" />

layout1b.xml:

<merge><TextView id="@+id/textView"><EditText hint="@+id/editText"></merge>


1
考虑到新的数据绑定内容,<include>现在更加常用了,attr覆盖是一个真正必须具备的功能
Dmitry Gryazin

1

我发现有时在Eclipse中使用GUI构建器时会错过包含android:id标记的信息。确保(当我注意到时)从构建器添加到TextView,即在ListView布局中使用的ID。

<TextView android:text="@+id/textView1"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />
...

变成

<TextView android:id="@+id/textView1"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />
...

而不是'false''false'我得到了:)并包括正常工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.