[Android]LayoutInflaterについて(生成,方法比較,実装)


概要

inflaterって何と思っていたので調べたまとめです。
自分なりの解釈を書いていきます。

目次

  • Androidのinflaterとは
  • Viewのinflateについて
  • LayoutInflaterからのviewの生成方法
  • 生成方法毎の違い
  • 疑問1:inflater.inflate(int resource, ViewGroup root, boolean attachToRoot)の第3引数は?
  • 疑問2:inflater.inflate(R.layout.sample, null, false);のnullって何?

Androidのinflaterとは

LayoutInflaterは、指定したxmlのレイアウト(View)リソースを利用できる仕組み

ちなみに
inflateの一般的な意味は、膨らませる、ふくらませるのような意味

Viewのinflateについて、LayoutInflaterからのviewの生成方法

よく見るやり方
1. context#getSystemService(Context.LAYOUT_INFLATER_SERVICE);
2. Layoutinflater.from(Context context)
3. View.inflate(Context context, int resource, ViewGroup root)  *これだけちょっと意味が違う

sample.java
//1 一般的な方法
LayoutInflater inflater = (LayoutInflater) context.SystemService(Context.LAYOUT_INFLATER_SERVICE);
//2 中身では1を実行しているので同様
LayoutInflater inflater = LayoutInflater.from(context);

//1,2でLayoutInflaterを作った後にViewを生成
View view = inflater.inflate(R.layout.layout_sample, root);  

/* 3 
staticでかつViewを一行でinflateできる
便利個人的によく使う、これも中身で2をコールして、1も実行される
Viewのinflaterメソッドなので、Layoutinflaterクラスのinflaterメソッドと引数が違うので注意!!
*/
View view = View.inflate(context, R.layout.layout_sample,root);  

生成方法毎の比較

2,3を利用しても、
下コードのように最終的にはgetSystemService(省略)をコールしている為ほぼ同等
どれを使ってもほぼ同じように使えそう。

/**
 * Obtains the LayoutInflater from the given context.
 */
public static LayoutInflater from(Context context) {
        LayoutInflater LayoutInflater =
                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (LayoutInflater == null) {
            throw new AssertionError("LayoutInflater not found.");
        }
        return LayoutInflater;
    }

疑問1:inflater.inflate(int resource, ViewGroup root, boolean attachToRoot)の第3引数は?

LayoutInflaterを使うときに、サンプルコードなどを見ていてattachToRootって思ったので調査

public View inflate (int resource, ViewGroup root, boolean attachToRoot)

ざっくりとはattachToRootにtrue,falseを指定したするとviewのルートが変わるらしい
true:rootで指定したものをルートにする
false:rootで指定したものをルートにしない

例)次のようなchild.xmlがある場合

child.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     android:orientation="vertical"">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</LinearLayout>

このようなコードがあった場合

//inflater作成
LayoutInflater inflater = LayoutInflater.from(this);
//適当なレイアウト
FrameLayout root = new FrameLayout(this);  

//inflate
View view = inflater.inflate(R.layout.child, root, true or false);  

つまり、
true:一番親のレイアウトがFrameLayout
false:一番親のレイアウトLinearLayout
となる。
フラグメントでinflateする場合にLayoutParamsのこと、を考えて少し考慮しておいた方が良さそう。

疑問2:inflater.inflate(R.layout.sample, null, false);のnullって何?

つまり、下記のrootをnullにした場合

View v = inflater.inflate(R.layout.sample, root, false); 

結局、仕組みを見ていくと下記のようになっていた、

public View inflate(int resource, ViewGroup root) {
        return inflate(resource, root, root != null);
   }

つまり、root が nullの場合attachToRootがfalseとなるということであった。
*疑問1に繋がった。

まとめ、感想

LayoutInflaterは色んなところでレイアウトリソースが使いまわせて便利!!
よくわからずに使うと致命的な問題になっている可能性もあるのでよくわかって使いましょう!
自分なりによくわかった気がする。解釈間違っていたら、コメントくださいmm

参考文献

LayoutInflater:http://developer.android.com/reference/android/view/LayoutInflater.html
LayoutInflater の生成方法、View の inflate 方法比較:http://qiita.com/s_of_p/items/821704f420f5b47103f2
Android カスタム ViewGroup 用XMLのルートタグを にする:
http://y-anz-m.blogspot.jp/2012/04/android-viewgroup.html