仕事で関わっているアプリのmasterブランチに Android Data Binding が導入されたのを見届けたので、自分でもちょっと使ってみました*1。
DataBidingのメリットや導入にあたってのハマりどころは以下のsys1yagiさんのエントリから:
- Android Data Binding Library 雑感 - visible true
- Data BindingとMultidexの兼ね合いの問題を大体倒したので実用段階待ったなし - visible true
さっそく個人アプリでも導入してみたところ、ドキュメントそのままだとGoogle Daggerとの相性が悪くてコンパイルが通りませんでした。これはstackoverflowで同じ問題が報告されていました。それによればDataBinding compilerを自分でdependenciesに書かなければならないとのこと。これでコンパイルは無事に通ります。
DataBinding自体は非常に多彩な機能があるのですが、ひとまずButterKnife+ViewHolderパターンの代替として使うと差分が非常に少なくてすみます
差分はこちら: Introduce DataBinding by gfx · Pull Request #13 · gfx/Android-Helium · GitHub
このPRは以下のことをやっただけです。
- layout XMLを
<layout>
タグで囲んでxmlns:*
を<layout>
に移動させる - ViewHolderクラスを消して
*Binding
に置き換える
*Binding
はlayout XMLから生成されるクラスで、普通のViewHolderとほぼ等しい機能を持ちます。たとえば ListViewの Adapter#getView()
の ButterKnife+ViewHolder な実装を DataBinding にする差分は以下のようになります。
@Override public View getView(int position, @Nullable View convertView, @Nullable ViewGroup parent) { if (convertView == null) { - convertView = LayoutInflater.from(getActivity()) - .inflate(R.layout.card_hatebu_entry, parent, false); - convertView.setTag(new ViewHolder()); + LayoutInflater inflater = LayoutInflater.from(getActivity()); + CardHatebuEntryBinding binding = DataBindingUtil.inflate(inflater, R.layout.card_hatebu_entry, parent, false); + convertView = binding.getRoot(); } - ViewHolder viewHolder = (ViewHolder) convertView.getTag(); - ButterKnife.inject(viewHolder, convertView); + CardHatebuEntryBinding binding = DataBindingUtil.getBinding(convertView);```
DataBindingUtil.inflate()
が LayoutInflater#inflate()
をしてViewと *Binding
を結びつける(bindする)メソッドで、 View#getTag()
で ViewHolder インスタンスを取得するかわりに DataBinding.getBinding()
で *Binding
インスタンスを取得します。 DataBinding
は内部で View#setTag()
をつかってbindingインスタンスを結びつけているので、実装的にもほとんどかわりありません。
一度ButterKnife+ViewHolderパターンとの対応がわかるとほとんど機械的に作業できるので、作業量的にも学習コスト的にも、DataBindingの導入コストは非常に低いといえます。