Edited at

Data Binding ライブラリの BindingAdapter と XML 名前空間

More than 3 years have passed since last update.

Data Binding ライブラリの BindingAdapter アノテーションの話。 (Data Binding ライブラリの 2.1 で確認した。)

Data Binding Guide によると、アプリケーション名前空間 (http://schemas.android.com/apk/res-auto) に属する XML 属性に対する独自セッター (custom setter) の定義方法は以下のような感じになっている。

@BindingAdapter({"bind:imageUrl", "bind:error"})

public static void loadImage(ImageView view, String url, Drawable error) {
Picasso.with(view.getContext()).load(url).error(error).into(view);
}

属性名のプレフィクスとして bind: が使われている。

だが、実際に上のようなコードを書いても、ビルド時に 『Application namespace for attribute bind:imageUrl will be ignored.』 みたいな警告が表示される。

実際にどうすればいいのかはちゃんとドキュメントには書かれてないので絶対に正しいかどうかはわからないが、おそらくはプレフィクスを何もつけないのがライブラリ開発者の想定している使い方だと思われる。 下のような感じ。

@BindingAdapter({"imageUrl", "error"})

警告を出すようになった変更自体は去年の 2015 年の 5 月にコミットされてる。

コミットメッセージには 『Give warning when BindingAdapter uses namespace.』 って書かれてる。 理由は謎。 『Bug 20725101』 というのもコミットメッセージに書かれてるけど、このバグがどれなのかはググってもわからなかった。 少なくとも AOSP のバグトラッカーに登録されているものではなさそう。

そんなわけで明確な理由はわからないけど、多分 『XML の名前空間接頭辞はあくまで XML の文書中で特定の名前空間 URI に紐づけられるものなので、Java のアノテーションでいきなり名前空間接頭辞が出てきてもそれが実際の名前空間 URI として何に紐づけられるべきなのか判断できない』 という理由で名前空間接頭辞は付けないようになったんじゃないかなーと思う。 つまり、基本的には全てアプリケーション名前空間に属する属性として扱うようになった、と。 ただ、アプリケーション名前空間と http://schemas.android.com/apk/res/android の名前空間の区別は必要なので、後者の名前空間を表すものとして例外的に android: は残されてるぽい。

Stack Overflow にもこの話題はあった。