1. ホーム
  2. kotlin

Kotlinのカスタム属性データバインディング

2023-11-13 15:30:24

質問

カスタム属性を設定するために Androidデータバインディングライブラリ を使ってカスタム属性を設定しようとしています。

レイアウト

<ImageView
    android:id="@+id/imgView”
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:layout_gravity="center"
    android:adjustViewBounds="true"
    app:imageUrl="@{segment.url}"/>
                            

コード

class Utils {
    companion object {
        @BindingAdapter("bind:imageUrl")
        @JvmStatic
        fun loadImage(view: ImageView, url:String) 
        {Picasso.with(view.context).load(url).error(R.drawable.error).into(view)}
    }
}

    

    

表示される実行時エラーは

<package.Utils.Companion> にあるBindingAdapterは静的ではなく、DataBindingComponentから取得した、使用するオブジェクトを必要とします。DataBindingComponentを取るインフレーションメソッドを使用しない場合は、DataBindingUtil.setDefaultComponentを使用するか、すべてのBindingAdapterメソッドをstaticにします。

解決するためのポインタがあれば教えてください。

これはカスタム属性にのみ発生します。残りのデータバインディングは問題なく動作します。

どのように解決するのですか?

トップレベルの関数を保持するだけで、クラスやコンパニオンオブジェクトは必要ありません。 FileNameKt で上書きされない限り @file:JvmName アノテーション

@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }

もう一つの方法として、Extension Functionにアノテーションを付ける方法があります。 @BindingAdapter バイトコードではシグネチャがDataBindingsが期待するシグネチャと正確に一致するのでうまくいきますが(生成されたメソッドは最初の引数として拡張クラスのオブジェクトを受け取ります)、関数もトップレベルのままであるべきです。

@BindingAdapter("imageUrl")
fun ImageView.loadImage(url:String) { ... }

もう一つの選択肢は BindingAdapter を拡張プロパティと組み合わせることです。

@set:BindingAdapter("visible")
var View.visible
    get() = visibility == VISIBLE
    set(value) {
        visibility = if (value) VISIBLE else GONE
    }