Android绑定适配器传递多个参数会导致错误

时间:2016-12-06 11:28:51

标签: android android-databinding

我是Android Data Binding的新人。我正在学习本教程:Data Binding Library。 我正在尝试使用接收多个参数的适配器。这是我的代码:

XML

   <ImageView
            android:layout_width="@dimen/place_holder_size"
            android:layout_height="@dimen/place_holder_size"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_centerVertical="true"
            app:url="@{image.imageUrl}"
            app:size="@{@dimen/place_holder_size}"
            />

绑定适配器类

public class ViewBindingAdapters extends BaseObservable {

@BindingAdapter({"bind:url", "bind:size"})
public static void loadImage(ImageView imageView, String url, int size) {
    if (!Strings.isNullOrEmpty(url)) {
        Picasso.with(imageView.getContext()).load(url).resize(size, size).centerCrop().into(imageView);
    }
}
....


}

但是我收到了这个错误:

  

java.lang.RuntimeException:发现数据绑定错误。   **** /数据绑定错误****消息:无法找到属性&#39; app:url&#39;在android.widget.ImageView上使用参数类型java.lang.String。   file:... li_image_item.xml   当地时间:30:27 - 30:40   **** \数据绑定错误****

有人知道为什么吗?

提前致谢!

6 个答案:

答案 0 :(得分:31)

问题是@dimen/place_holder_size,当您将其作为float

捕获时,它会返回int

将您的BindingAdapter方法更改为此

@BindingAdapter({"bind:url", "bind:size"})
public static void loadImage(ImageView imageView, String url, float size) {

}

您可以参考this

答案 1 :(得分:6)

我做错了的是函数中参数的顺序。您可以在“绑定适配器”中添加多个属性,但是它们应与方法中定义的顺序相同的参数相匹配

这是我的Kotlin代码段

@BindingAdapter(value = ["bind:brand", "bind:model", "bind:age"], requireAll = false)
@JvmStatic
fun bindProductDetails(linearLayout: LinearLayout, brand: String?, model: String?, age: String?) {
    if (brand != null && !brand.isEmpty()) {
        //code
        //code

    }
}

答案 2 :(得分:4)

试试这个

 @BindingAdapter(value={"url", "size"}, requireAll=false)
 public static void loadImage(ImageView imageView, String url, int size) {
        if (!Strings.isNullOrEmpty(url)) {
            Picasso.with(imageView.getContext()).load(url).resize(size, size).centerCrop().into(imageView);
        }
    }

答案 3 :(得分:4)

除了上面由@Kishan Solanki提供的示例外,并且随着数据绑定库中发生的更改,您所需要做的就是用逗号分隔的值声明它们。例子

@BindingAdapter("loadImageFrom", "widthDp")
fun loadImages(imageView: ImageView, url: String?, widthDp: Int) {
    url?.let {

        val height = (widthDp / 3) * 4
        val fullUrl = getImagePosterUrl(url)
        Picasso.get().load(fullUrl).resize(widthDp.px, height.px).into(imageView)
    }

}

最要记住的一点是,您以DataBinding格式将数据提供给适配器属性。

示例,您必须编写将Int作为XML参数提供

app:widthDp="@{120}"

app:your_attribute =“ @ {your_data}”

P。 S.-哦,还有件事,widthDp **。px **是一个扩展函数,它根据屏幕密度将dp值的Int转换为相关的像素值。因此,请不要感到困惑。

答案 4 :(得分:2)

更新

您无需创建前缀bind:,只需使用它即可。

@BindingAdapter({"url", "size"})
public static void loadImage(ImageView imageView, String url, float size) {

}

在xml中使用app:之类的任何前缀

app:url="@{image.imageUrl}"

答案 5 :(得分:0)

https://developer.android.com/topic/libraries/data-binding/binding-adapters

@BindingAdapter(value = ["imageUrl", "placeholder"], requireAll = false)
fun ImageView.setImageUrl(url: String?, placeHolder: Drawable?) {
    if (url == null) {
        setImageDrawable(placeholder)
    } else {
        MyImageLoader.loadInto(this, url, placeholder)
    }
}

请注意,BindingAdapter 属性和 setImageUrl 参数可能具有不同的名称。但它们应该以相同的顺序进行。如果其中一些属性在 XML 中定义(在此示例中为 ImageView),则将调用此方法。

<ImageView 
    app:imageUrl="@{venue.imageUrl}"
    app:placeholder="@{@drawable/venueError}" />

属性应该与方法中定义的类型相同。您也可以使用 listeners。使用 interfaces 代替 Kotlin lambda。