この attachToRoot に true を指定した場合と false にした場合で返ってくるルートビューが異なります。
例えば
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello" />
- </LinearLayout>
- LayoutInflater inflater = getLayoutInflater();
- FrameLayout root = new FrameLayout(this);
- View v = inflater.inflate(R.layout.main, root, true);
一方、
- View v = inflater.inflate(R.layout.main, root, false);
- View v = inflater.inflate(R.layout.main, null, true);
- View v = inflater.inflate(R.layout.main, null, false);
inflater.inflate(R.layout.main, root, false)
と
inflater.inflate(R.layout.main, null, false)
の違いは、root が null でない場合はそれに合うような LayoutParams が返ってくるルートビューにセットされるという点です。
http://tools.oesf.biz/android-4.0.1_r1.0/xref/frameworks/base/core/java/android/view/LayoutInflater.java#471
- 471 if (root != null) {
- 472 if (DEBUG) {
- 473 System.out.println("Creating params from root: " +
- 474 root);
- 475 }
- 476 // Create layout params that match root, if supplied
- 477 params = root.generateLayoutParams(attrs);
- 478 if (!attachToRoot) {
- 479 // Set the layout params for temp if we are not
- 480 // attaching. (If we are, we use addView, below)
- 481 temp.setLayoutParams(params);
- 482 }
- 483 }
- 424 public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {
- 453 if (TAG_MERGE.equals(name)) {
- 454 if (root == null || !attachToRoot) {
- 455 throw new InflateException("<merge /> can be used only with a valid "
- 456 + "ViewGroup root and attachToRoot=true");
- 457 }
- 458
- 459 rInflate(parser, root, attrs, false);
- 460 } else {
考えてみれば当たり前ですね。<merge> タグは addView されたときに親の View と合体するということなので、合体対象がいない場合戻り値の View として返すものがなくなってしまいます。
どういう場面で <merge> タグのレイアウトを inflate() することがあるかというとオリジナルの ViewGroup を作る場合です。
例えば、ボタンが縦に3つ並んだ LinearLayout をオリジナルの ViewGroup にしたいとします。
つまり、
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello" />
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
- <Button
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Button" />
- <Button
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Button" />
- <Button
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Button" />
- </LinearLayout>
- </LinearLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello" />
- <yanzm.example.viewgroupmerge.MyViewGroup
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
そのためには、この MyViewGroup 自身に縦に並ぶボタン3つを持たせる必要があります。
初心者がやりがちなのがこういうコードです。
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
- <Button
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Button" />
- <Button
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Button" />
- <Button
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Button" />
- </LinearLayout>
- public class MyViewGroup extends FrameLayout {
- public MyViewGroup(Context context) {
- super(context);
- init(context);
- }
- public MyViewGroup(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
- public MyViewGroup(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(context);
- }
- private void init(Context context) {
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View v = inflater.inflate(R.layout.custom_layout, null, false);
- addView(v);
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <merge xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" >
- <Button
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Button" />
- <Button
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Button" />
- <Button
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Button" />
- </merge>
- public class MyViewGroup extends LinearLayout {
- public MyViewGroup(Context context) {
- super(context);
- init(context);
- }
- public MyViewGroup(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
- public MyViewGroup(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- init(context);
- }
- private void init(Context context) {
- setOrientation(LinearLayout.VERTICAL);
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View v = inflater.inflate(R.layout.custom_layout, this, true);
- }
- }
さらに、View には inflate(Context context, int resource, ViewGroup root) という static メソッドがあり、 このメソッドを使ってさらに簡単に書けます。
- private void init(Context context) {
- setOrientation(LinearLayout.VERTICAL);
- View.inflate(context, R.layout.custom_layout, this);
- }
- LayoutInflater inflater = activity.getLayoutInflater();
- LayoutInflater inflater = LayoutInflater.from(Context context);
- LayoutInflater inflater = (LayoutInflater) context.SystemService(Context.LAYOUT_INFLATER_SERVICE);
0 件のコメント:
コメントを投稿