可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am trying to set custom attribute using the Android DataBinding Library
in my Kotlin project like this:
Layout
<ImageView
android:id="@+id/imgView”
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:adjustViewBounds="true"
app:imageUrl="@{segment.url}"/>
Code
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)}
}
The runtime error I get is:
A BindingAdapter in in is not static and requires an object to use, retrieved from the DataBindingComponent. If you don't use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.
Any pointers to solve it?
This happens only for custom attributes. The rest of the databindings work fine
回答1:
Just keep function on the top level, no class or companion object needed, it will work since top-level functions in Kotlin translated to static member functions of Class named as FileNameKt
unless overridden by @file:JvmName
annotation
@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
One more option is to annotate Extension Function as @BindingAdapter
, it will work since in bytecode signature will exactly match signature expected by DataBindings(generated method will still accept an object of the extended class as the first argument), the function should remain top level as well
@BindingAdapter("imageUrl")
fun ImageView.loadImage(url:String) { ... }
回答2:
Try switching the order of the annotations. It seems to fix the issue:
class Utils {
companion object {
@JvmStatic @BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
}
}
The problem is that the databindng compiler uses getCompanion().loadImage
otherwise*.
You can verify this in the generated com.your.package.databinding.*Binding
class
* After playing around a bit I noticed that this has nothing to do with the order of the annotations, but seems to be random. It seems to change whenever I hit "rebuild". It might be a bug in kapt
or in the kotlin compiler
回答3:
Adding @JvmStatic
after @BindingAdapter("imageUrl")
fixed my problem.
For ex:
@BindingAdapter("android:visibility")
@JvmStatic
fun setVisibility(view: View, visible: Boolean) {
view.visibility = if (visible) View.VISIBLE else View.GONE
}
}
回答4:
Or using extension:
@BindingAdapter("imageUrl")
fun ImageView.setImageUrl(url: String?) {
Picasso.with(context).load(url).into(this)
}
Now you can use this function anywhere else
回答5:
The function(loadImage) need to put in object(Singleton in java) not in class and set @JvmStatic
before @BindingAdapter("imageUrl")
like this :
<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)
}
回答6:
This is working for me. Please find it below..
Add in gradle:
apply plugin: 'kotlin-kapt'
dependencies {
kapt "com.android.databinding:compiler:3.1.4"
}
Add in POJO:
companion object {
@BindingAdapter("image")
@JvmStatic
fun loadImage(view: ImageView, imageUrl: String) {
//am Using Glide
Glide.with(view.context).setDefaultRequestOptions(RequestOptions().circleCrop())
.load(imageUrl).into(view)
}
}
In Layout:
Add bind:image="@{movies.imageUrl}
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
bind:image="@{movies.imageUrl}/>
回答7:
This worked for me
object ImageUtils {
@JvmStatic @BindingAdapter("imageUrl")
fun ImageView.loadImage(url: String?){
GlideHelper.loadImage(url,this)
}
}
in xml like this:
imageUrl="@{file.thumbnailLink}"