仕事で関わっているアプリの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の導入コストは非常に低いといえます。