我正在尝试使用Android数据库绑定库设置自定义属性在我的Kotlin项目中,像这样:
布局<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
不是静态的,需要一个对象来使用,从DataBindingComponent中检索。如果你不使用一个以DataBindingComponent为参数的膨胀方法,那就使用DataBindingUtil。setDefaultComponent或将所有BindingAdapter方法设置为静态
有解决的方法吗?
这只发生在自定义属性上。其余的数据绑定可以正常工作
只要将函数保持在顶层,不需要类或同伴对象,它将工作,因为Kotlin中的顶层函数转换为名为FileNameKt
的类的静态成员函数,除非被@file:JvmName
注释覆盖
@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
另一个选择是将扩展函数注释为@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
}
尝试切换注释的顺序。它似乎解决了这个问题:
class Utils {
companion object {
@JvmStatic @BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
}
}
问题是数据绑定编译器使用getCompanion().loadImage
否则*。
您可以在生成的com.your.package.databinding.*Binding
类
*在玩了一会儿之后,我注意到这与注释的顺序无关,但似乎是随机的。每当我点击"重建"时,它似乎就会改变。这可能是kapt
或kotlin编译器中的错误
在@BindingAdapter("imageUrl")
之后添加@JvmStatic
解决了我的问题。
@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)
}
现在你可以在任何地方使用这个函数
这对我来说很有效。
添加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)
}
}
在布局:添加绑定:图像= " @ {movies.imageUrl}
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
bind:image="@{movies.imageUrl}/>
函数(loadImage)需要放在对象(java中的Singleton)中,而不是放在类中,并且像这样将@JvmStatic
设置在@BindingAdapter("imageUrl")
之前:
<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)
}
这对我有用
object ImageUtils {
@JvmStatic @BindingAdapter("imageUrl")
fun ImageView.loadImage(url: String?){
GlideHelper.loadImage(url,this)
}
}
XML中的:
imageUrl="@{file.thumbnailLink}"