stableバージョンが出たようなので乗り換えてみる。
まず試してみるのは「データバインディング」かな。
classpath ‘com.android.tools.build:gradle:1.3.0’
classpath ‘com.android.databinding:dataBinder:+’
apply plugin: ‘com.android.databinding’
本格的なのは後にするとして、findViewByIdの排除系を。
レイアウトの xmlにてルート要素を layoutにすると、xmlのファイル名をベースとしたバインダーが生成される。*1
このバインダーにはレイアウト内で idの振られているビューがメンバー*2 として含まれているのでわざわざ idで findViewByIdを呼ばなくてもアクセスが可能になる。
ListView等で使われる Holderを自動で定義してくれるような感じ。
これは便利だ。
ただ、アクティビティにて setContentViewを使うサンプルばかりで、フラグメントで使っている物が見あたらないので少し悩んでみた。
onCreateViewにて、バインダーの inflateメソッドを使ってバインダーを作成し、バインダーの getRootで得られる Viewを返すというのが正解…なんだと思う。
ListViewの要素の場合はずばりバインダーを holder代わりにすればいいし、RecyclerViewなら ViewHolder.itemViewに getRootをわたし、要素としてバインダーを持てばいいと。
難があるとすれば、stableになったにもかかわらず「ビルドしてみると出来るけど、IDE上ではエラーとして表示される」状態が直ってない点か。
「単語の先頭は大文字、ただし先頭の単語は全て小文字」という命名規則を守らないと自動生成されたコードと食い違ってエラーになってしまう。
本格的に使うようになるとレイアウト中に式を書くのだけど、慣れないうちはエラーになった場合に問題を調べるのが困難だ。
TextViewの styleのように独立した Setterが存在しない属性についてはカスタムセッターを作る。*3
TextUtils.isEmptyを使い、テキストが空の時は Visibilityに GONEを設定したいなんて時に android:visibility=”@{TextUtils.isEmpty(firstName) ? View.GONE : View.VISIBLE}”なんて書きたくなるけど、残念ながらエラーに。
生成されたコードに TextUtilsや Viewのインポート文が含まれていないというのがその理由。
そんなときは dataタグの子供として <import type=”android.view.View”/>や <import type=”android.text.TextUtils”/>を書いてやればいい。
意味はそのまんま。
ただ、import指定にしろ、@{}の中身にしろコード補完の類が効かないのでそれなりに面倒なのよね。
将来的にはどうにかなるのかしら?
日本語の資料を探すと同じような内容ばかり出てくるけど、結局の所一次情報である Data Binding Guideをあたるのが一番早い。