【问题标题】:Does Android XML Layout's 'include' Tag Really Work?Android XML 布局的“包含”标签真的有效吗?
【发布时间】:2011-02-07 13:33:59
【问题描述】:

在我的 Android 布局文件中使用 时,我无法覆盖属性。搜索bug的时候发现DeclinedIssue 2863

“包含标签已损坏(覆盖布局参数永远不会起作用)”

由于 Romain 表示这在测试套件和他的示例中有效,我一定是做错了什么。

我的项目是这样组织的:

res/layout
  buttons.xml

res/layout-land
  receipt.xml

res/layout-port
  receipt.xml

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

纵向和横向的receipt.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>

我错过了什么?

【问题讨论】:

  • 当您尝试以不受支持的方式使用包含时,Android 开发人员工具会引用此问题。

标签: android android-widget


【解决方案1】:

我刚刚发现了问题。首先,您只能覆盖 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);
   }
}

如果 标签不包含 both layout_width 和 layout_height,则会发生 RuntimeException 并被静默处理,甚至没有任何日志语句。

如果您想覆盖任何 layout_* 属性,解决方案是在使用 标记时始终包含 layout_width 和 layout_height。

我的例子应该改为:

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

【讨论】:

  • 这太荒谬了。我从来没有能够让它工作,我什至看到文档提到如果试图覆盖尺寸,我认为它需要高度和宽度,我认为这是高度和宽度。但是,我试图覆盖的只是边距,这并不是一个真正的维度。当我想要更改的只是 layout_marginRight 时,为什么我需要同时指定这两个甚至其中任何一个? Grrr,Android,有时你太让我沮丧了。
  • FYI Android Lint 会给你一个错误(布局参数 layout_height 被忽略,除非 layout_width 也在 标签上指定)如果你没有同时覆盖高度和宽度属性
【解决方案2】:

我提交了enhancement request 以允许覆盖所有包含的属性:

假设我有两个相同的布局,而不是 a 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>

【讨论】:

  • 考虑到新的数据绑定的东西,&lt;include&gt; 现在使用得更多了,attr 覆盖是一个真正必须具备的功能
【解决方案3】:

我发现在 Eclipse 中使用 GUI 构建器时有时会错过包含 android:id 标记。确保(当我注意到)我从 builder 添加到 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' 而不是 :) 并且包括工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 2011-05-02
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    相关资源
    最近更新 更多