ビュー階層と要素

Androidのビューを構成するためのレイアウトをXMLで作成する場合、ルート要素にはなんらかのコンテナクラスの要素(ViewGroupの派生クラスを表す要素、例えばLinearLayout)を記述しなくてはならないというルールがある。

例えば、以下のように構成されたビュー階層があったとしよう。

この画面に対してサブコンテンツとして以下のようなXMLで構成されたレイアウトを上記ビューのLayer1階層に追加したいとする。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/LinearLayoutMerge"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="vertical"
  >
 <TextView
  android:id="@+id/TextViewMerge"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textSize="14sp"
  android:background="#00000000"
  android:text="Merge Content"
  android:textColor="#FF000000"
  />
<Button
 android:id="@+id/ButtonMerge"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Merge Layer Button"
 />
 </LinearLayout>
  • コード (LayoutMergeTest.java)
public class LayoutMergeTest extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.main);
        LinearLayout l1 = (LinearLayout)this.findViewById(R.id.LinearLayout01);
        LayoutInflater.from(this).inflate(R.layout.sub, l1, true);
    }
}
  • 実行結果

この時に流し込むビューはTextViewとButtonだけなのだが、最初に書いたようにルート要素にコンテナ要素が必要なため、無駄なのは解りつつもLinerLayoutが必要になる訳だ。

このような時にはレイアウトXMLのルート要素を使用することでコンテナ要素を省くことができる。

  • merge.xml (sub.xmlのルート要素をmergeに変えただけのもの)
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
 android:id="@+id/TextViewMerge"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:textSize="14sp"
 android:background="#00000000"
 android:text="Merge Content"
 android:textColor="#FF000000"/>
<Button
 android:id="@+id/ButtonMerge"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Merge Layer Button" />
</merge>

実行結果は変わらないので割愛するが、Hierarchy Viwerで見てみるとTextViewとButtonがLinearLayout01に直接ぶら下がっているの(赤線で括った部分)が判るだろう。