Android XML Layout的'include'标签真的有用吗?

Eri*_*rke 84 android android-widget

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

"包括标签被破坏(覆盖布局参数永远不会起作用)"

由于Romain表明这在测试套件及其示例中有效,因此我必须做错事.

我的项目组织如下:

res/layout
  buttons.xml

res/layout-land
  receipt.xml

res/layout-port
  receipt.xml
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

肖像和横向的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>
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Eri*_*rke 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);
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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

我的例子应该改为:

<include
      android:id="@+id/buttons_override"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      layout="@layout/buttons"/>
Run Code Online (Sandbox Code Playgroud)

  • 这是荒唐的.我从来没有能够让这个工作,我甚至看到文件提到需要高度和宽度,如果试图覆盖尺寸,我认为是高度和宽度.但是,我试图覆盖的只是保证金,这实际上并不是一个维度.当我想要改变的是layout_marginRight时,为什么我需要指定那些甚至任何一个?Grrr,Android,有时候你太沮丧了. (33认同)
  • Eric,您应该接受自己的答案作为解决方案. (2认同)

Jef*_*rod 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>