web-dev-qa-db-ja.com

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

次のように、Kotlinプロジェクトで Android DataBinding Library を使用してカスタム属性を設定しようとしています。

レイアウト

<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)}
    }       

私が得るランタイムエラーは次のとおりです:

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

それを解決するためのポインタはありますか?

これは、カスタム属性に対してのみ発生します。残りのデータバインディングは正常に動作します

51
Akshata

クラスまたはコンパニオンオブジェクトを必要としないトップレベルの関数を保持するだけで、@file:JvmNameアノテーションによってオーバーライドされない限り、Kotlinのトップレベル関数がFileNameKtという名前のクラスの静的メンバー関数に変換されるため、機能します

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

もう1つのオプションは、拡張関数に@BindingAdapterとして注釈を付けることです。これは、バイトコード署名がDataBindingsによって期待される署名と完全に一致するために機能します(生成されたメソッドは、最初の引数として拡張クラスのオブジェクトを受け入れます)同様にトップレベルのまま

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

注釈の順序を切り替えてみてください。問題を解決するようです:

_class Utils {
    companion object {
        @JvmStatic @BindingAdapter("imageUrl")
        fun loadImage(view: ImageView, url:String) { ... } 
    }
} 
_

問題は、databindngコンパイラがgetCompanion().loadImageを使用することです*
これは、生成された_com.your.package.databinding.*Binding_クラスで確認できます

* 少し遊んだ後、私はこれが注釈の順序とは関係ないことに気づきましたが、ランダムであるようです。 「再構築」を押すたびに変わるようです。 kaptまたはkotlinコンパイラのバグである可能性があります

26
Lovis

@BindingAdapter("imageUrl")の前に_@JvmStatic_を追加すると、問題が修正されました。

例:

object BindingAdapters { @BindingAdapter("Android:visibility") @JvmStatic fun setVisibility(view: View, visible: Boolean) { view.visibility = if (visible) View.VISIBLE else View.GONE } }

または拡張機能を使用します:

@BindingAdapter("imageUrl")
fun ImageView.setImageUrl(url: String?) {
    Picasso.with(context).load(url).into(this)
}

これで、この関数をどこでも使用できます

2
Yazazzello

これは私のために働いた

object ImageUtils {

        @JvmStatic @BindingAdapter("imageUrl")
        fun ImageView.loadImage(url: String?){
                GlideHelper.loadImage(url,this)
        }
}

このようなXMLで:

imageUrl="@{file.thumbnailLink}"
1
Yogesh Paliyal

Function(loadImage)は、クラスではなくオブジェクト(Javaではシングルトン)に配置し、@BindingAdapter("imageUrl")の前に@JvmStaticを次のように設定する必要があります。

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

   @JvmStatic
   @BindingAdapter("bind:imageUrl")
   fun ImageView.loadImage( url:String) {
Picasso.with(this.context).load(url).error(R.drawable.error).into(this)
}
1
Fidan Bacaj