web-dev-qa-db-ja.com

Android XML Layoutの 'include'タグは本当に機能しますか?

Androidレイアウトファイルで<include>を使用すると、属性をオーバーライドできません。バグを検索したときに、拒否されました Issue 286

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

そして、portrait.landscape.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>

私は何が欠けていますか?

84
Eric Burke

問題を見つけました。まず、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>タグにboth 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"/>
132
Eric Burke

拡張要求 を送信して、含まれているすべての属性をオーバーライドできるようにします。

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>

10
Jeff Axelrod

EclipseでGUIビルダーを使用しているときに、Android:idタグを含めることができないことがあります。 ListViewレイアウトで使用しているidを、builderからTextViewに追加することを確認します(気づいたとき)。

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

1
TheSolarSheriff