Kotlin 自定义属性数据绑定
Kotlin custom attribute databinding
我正在尝试使用 Android DataBinding Library 设置自定义属性
在我的 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)}
}
}
我得到的运行时错误是:
A BindingAdapter in in <package.Utils.Companion> 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.
有什么解决办法吗?
这仅适用于自定义属性。其余的数据绑定工作正常
尝试调换注释的顺序。它似乎解决了这个问题:
class Utils {
companion object {
@JvmStatic @BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
}
}
问题是databindng编译器使用getCompanion().loadImage
否则*.
您可以在生成的 com.your.package.databinding.*Binding
class
中验证这一点
* 玩了一会儿后,我注意到这与注释的顺序无关,但似乎是随机的。每当我点击 "rebuild" 时它似乎都会改变。这可能是 kapt
或 kotlin 编译器
中的错误
只需将函数保持在顶层,不需要 class 或伴随对象,它将工作,因为 Kotlin 中的顶层函数被翻译成 Class 的静态成员函数,命名为 FileNameKt
除非被 @file:JvmName
注释覆盖
@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
另一种选择是将扩展函数注释为 @BindingAdapter
,它将起作用,因为在字节码签名中将完全匹配 DataBindings 期望的签名(生成的方法仍将接受扩展的对象 class作为第一个参数),函数也应该保持在顶层
@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
}
在 @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)
}
现在您可以在其他任何地方使用此功能
函数(loadImage)需要放入object(Singleton in java)而不是class并且在@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)
}
这对我有用
object ImageUtils {
@JvmStatic @BindingAdapter("imageUrl")
fun ImageView.loadImage(url: String?){
GlideHelper.loadImage(url,this)
}
}
在 xml 中像这样:
imageUrl="@{file.thumbnailLink}"
这对我有用。请在下面找到它..
加入gradle:
apply plugin: 'kotlin-kapt'
dependencies {
kapt "com.android.databinding:compiler:3.1.4"
}
在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)
}
}
布局中:
添加bind:image="@{movies.imageUrl}
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
bind:image="@{movies.imageUrl}/>
我正在尝试使用 Android DataBinding Library 设置自定义属性 在我的 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)}
}
}
我得到的运行时错误是:
A BindingAdapter in in <package.Utils.Companion> 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.
有什么解决办法吗?
这仅适用于自定义属性。其余的数据绑定工作正常
尝试调换注释的顺序。它似乎解决了这个问题:
class Utils {
companion object {
@JvmStatic @BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
}
}
问题是databindng编译器使用getCompanion().loadImage
否则*.
您可以在生成的 com.your.package.databinding.*Binding
class
* 玩了一会儿后,我注意到这与注释的顺序无关,但似乎是随机的。每当我点击 "rebuild" 时它似乎都会改变。这可能是 kapt
或 kotlin 编译器
只需将函数保持在顶层,不需要 class 或伴随对象,它将工作,因为 Kotlin 中的顶层函数被翻译成 Class 的静态成员函数,命名为 FileNameKt
除非被 @file:JvmName
注释覆盖
@BindingAdapter("imageUrl")
fun loadImage(view: ImageView, url:String) { ... }
另一种选择是将扩展函数注释为 @BindingAdapter
,它将起作用,因为在字节码签名中将完全匹配 DataBindings 期望的签名(生成的方法仍将接受扩展的对象 class作为第一个参数),函数也应该保持在顶层
@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
}
在 @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)
}
现在您可以在其他任何地方使用此功能
函数(loadImage)需要放入object(Singleton in java)而不是class并且在@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)
}
这对我有用
object ImageUtils {
@JvmStatic @BindingAdapter("imageUrl")
fun ImageView.loadImage(url: String?){
GlideHelper.loadImage(url,this)
}
}
在 xml 中像这样:
imageUrl="@{file.thumbnailLink}"
这对我有用。请在下面找到它..
加入gradle:
apply plugin: 'kotlin-kapt'
dependencies {
kapt "com.android.databinding:compiler:3.1.4"
}
在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)
}
}
布局中:
添加bind:image="@{movies.imageUrl}
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
bind:image="@{movies.imageUrl}/>