次のように、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メソッドを静的にします。
それを解決するためのポインタはありますか?
これは、カスタム属性に対してのみ発生します。残りのデータバインディングは正常に動作します
クラスまたはコンパニオンオブジェクトを必要としないトップレベルの関数を保持するだけで、@file:JvmName
アノテーションによってオーバーライドされない限り、Kotlinのトップレベル関数がFileNameKt
という名前のクラスの静的メンバー関数に変換されるため、機能します
@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
もう1つのオプションは、拡張関数に@BindingAdapter
として注釈を付けることです。これは、バイトコード署名がDataBindingsによって期待される署名と完全に一致するために機能します(生成されたメソッドは、最初の引数として拡張クラスのオブジェクトを受け入れます)同様にトップレベルのまま
@BindingAdapter("imageUrl")
fun ImageView.loadImage(url:String) { ... }
注釈の順序を切り替えてみてください。問題を解決するようです:
_class Utils {
companion object {
@JvmStatic @BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
}
}
_
問題は、databindngコンパイラがgetCompanion().loadImage
を使用することです*。
これは、生成された_com.your.package.databinding.*Binding
_クラスで確認できます
* 少し遊んだ後、私はこれが注釈の順序とは関係ないことに気づきましたが、ランダムであるようです。 「再構築」を押すたびに変わるようです。 kapt
またはkotlinコンパイラのバグである可能性があります
@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)
}
これで、この関数をどこでも使用できます
これは私のために働いた
object ImageUtils {
@JvmStatic @BindingAdapter("imageUrl")
fun ImageView.loadImage(url: String?){
GlideHelper.loadImage(url,this)
}
}
このようなXMLで:
imageUrl="@{file.thumbnailLink}"
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)
}