Android XML Layoutの「include」タグは実際に機能しますか?


84

Androidレイアウトファイルで<include>を使用すると、属性を上書きできません。バグを検索したところ、Declined Issue2863が見つかりました。

「includeタグが壊れています(レイアウトパラメータのオーバーライドは機能しません)」

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>

また、縦向きと横向きの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 2018

回答:


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);
   }
}

<include>タグに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
高さと幅の両方の属性をオーバーライドしていない場合、FYI Android Lintはエラーを出します(layout_widthも<include>タグで指定されていない限り、レイアウトパラメーターlayout_heightは無視されます)
バイナリ

10

含まれているすべての属性をオーバーライドできるようにする拡張リクエストを送信しました。

TextViewフィールドの値以外に2つの同じレイアウトがあるとし ます。現在、実行時にレイアウトを変更するか、XMLを複製しています。

たとえば、値が「hello」と「world」の2つのパラメータを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の

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'を取得する代わりに、:)を取得し、正常に動作することを含みます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.