Android XML 布局的“包含”标签真的有效吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2631614/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:40:10  来源:igfitidea点击:

Does Android XML Layout's 'include' Tag Really Work?

androidandroid-widget

提问by Eric Burke

I am unable to override attributes when using <include> in my Android layout files. When I searched for bugs, I found Declined Issue 2863:

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

"include tag is broken (overriding layout params never works)"

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

Since Romain indicates this works in the test suites and his examples, I must be doing something wrong.

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

My project is organized like this:

我的项目是这样组织的:

res/layout
  buttons.xml

res/layout-land
  receipt.xml

res/layout-port
  receipt.xml

The buttons.xml contains something like this:

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>

And the portrait and landscape receipt.xml files look something like:

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

What am I missing?

我错过了什么?

回答by Eric Burke

I just found the issue. First, you can only override layout_* attributes, so the background won't work. That is documented behavior and simply an oversight on my part.

我刚刚发现了这个问题。首先,您只能覆盖 layout_* 属性,因此背景不起作用。这是记录在案的行为,只是我的疏忽。

The real problem is found in LayoutInflater.java:

真正的问题是在 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);
   }
}

If the <include> tag does not include bothlayout_width and layout_height, the RuntimeException occurs and is silently handled, without any log statement even.

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

The solution is to always include both layout_width and layout_height when using the <include> tag, if you want to override any of the layout_* attributes.

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

My example should change to:

我的例子应该改为:

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

回答by Jeff Axelrod

I submitted an enhancement requestto allow all included attributes to be overridden:

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

Suppose I have two identical layouts other than the values of a TextViewfield. Presently, I either have modify the layout at runtime or duplicate the XML.

For example to pass two parameters with values "hello" and "world" to layout1:

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

layout1a.xml:

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

An alternate implementation would break encapsulation and would allow the include statement to override values like:

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

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

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

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

布局1a.xml:

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

另一种实现将破坏封装并允许包含语句覆盖如下值:

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

布局1b.xml:

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

回答by TheSolarSheriff

I found I sometimes miss including the android:id tag when using the GUI builder in Eclipse. Making sure (when I notice) that I add into a TextView from the builder , the id I'm using in the ListView layout.

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

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

becomes

变成

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

Instead of getting 'false' 'false' I get :) and includes working ok.

而不是得到“假”“假”我得到:)并且包括工作正常。