書き物

技術とか作った物の話とか愚痴文句感想など

Android の Data Binding の DataBindingUtil を調べた

前回から Android の Data Binding 機能を試しています。 Activity や DialogPreference で試していたのですが、Activity ではうまくいったものが DialogPreference ではうまくいきませんでした。 色々探った所、DataBindingUtil の機能を理解していないせいだったようです。 DataBindingUtil のよく使いそうなメソッドの意味を調査しましたのでメモを残します。

Activity で使うもの ↓コレ T DataBindingUtil.setContentView(Activity activity, int layoutId)

通常 Activity で layout.xml を適用する場合、 @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); } としますが、Data Binding を利用する場合に DataBindingUtil.setContentView() を使うようです。 以下の様な感じです。 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

    // Data Binding 準備
    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.setViewModel(mViewModel);
}

これで Data Binding の利用と、layout.xml の適用がされます。

Activity 以外で使うもの ↓コレ T DataBindingUtil.inflate(LayoutInflater inflater, int layoutId, @Nullable ViewGroup parent, boolean attachToParent) Fragment や DialogPreference、ListView のアイテムに適用するレイアウトなどに対して Data Binding を利用する場合に使えそうです。 今回試したのは DialogPreference のカスタマイズだったので、それを例にします。

通常 DialogPreference へ独自の layout.xml を適用する場合、onCreateDialogView() が呼ばれる前に setDialogLayoutResource() でリソース ID を設定する、もしくは onCreateDialogView() 内でレイアウトを適用した View を return します。

Fragment もそうですが、View を return することで layout.xml を適用するようなパターンで、DataBindingUtil.inflate() を利用すれば良さそうです。

以下の様な感じです。(DialogPreference のサブクラスにて) @Override protected View onCreateDialogView() { // Data Binding 準備 FileSelectorBinding binding = DataBindingUtil.inflate( LayoutInflater.from(getContext()), R.layout.file_selector, null, false ); binding.setViewModel(mViewModel);

    return binding.getRoot();
}

また、「[Android] – Data Bindingつかってみた | NET BIZ DIV. TECH BLOG」で ListView のアイテムに Data Binding を利用する layout.xml を使う場合の参考コードがありますが、これも View を返すことでレイアウトを適用するパターンです。 DialogPreference に ListView を仕込んで、アイテムに独自の layout.xml を適用し、Data Binding しましたが、うまくいきました。 (ArrayAdapter のサブクラスにて) @Override public View getView(int position, View convertView, ViewGroup parent) { FileSelectorItemBinding binding;

    // 1 周目ではアイテムの View が作成されていないので
    if (convertView == null)
    {
        // リストのアイテムにレイアウト適用と Data Binding を適用する
        binding = DataBindingUtil.inflate(
                LayoutInflater.from(getContext()),
                R.layout.file_selector_item,
                parent,
                false
            );
        // レイアウトを適用したアイテムの View を取得
        convertView = binding.getRoot();
    }
    // 2 周目ではアイテムの View が作成されているので
    else
    {
        // Data Binding オブジェクトを View から取得
        binding = DataBindingUtil.getBinding(convertView);
    }

    // Data Binding するために View と ViewModel を紐つける
    binding.setViewModel(getItem(position));

    // アイテムの View を返す
    return convertView;
}

おわりに このあたりが分かっていれば、基本的な使い方は出来そうです。 DataBindingUtil は実は裏で setContentView() を実行していたりと、親切なのか罠なのか、結局ソースを解析しなければ意味が理解できませんでした。 まだ日本語の情報が少ないので、使いながらコツコツ覚えていきたいです。