Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android binding adapter passing multiple arguments cause error

I am quite new in Android Data Binding. I am following this tutorial: Data Binding Library. I am trying to do an adapter that receive multiple parameters. This is my code:

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}"
            />

BINDING ADAPTER CLASS

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);
    }
}
....


}

But I am getting this error:

java.lang.RuntimeException: Found data binding errors. ****/ data binding error ****msg:Cannot find the setter for attribute 'app:url' with parameter type java.lang.String on android.widget.ImageView. file:... li_image_item.xml loc:30:27 - 30:40 ****\ data binding error ****

Does anybody know why??

Thanks in advance!

like image 753
IrApp Avatar asked Dec 06 '16 11:12

IrApp


People also ask

Is data binding good in Android?

Using data binding can lead to faster development times, faster execution times and more readable and maintained code. Android data binding generates binding classes at compile time for layouts.

What is the use of binding adapter in android?

Binding adapters are responsible for making the appropriate framework calls to set values. One example is setting a property value like calling the setText() method. Another example is setting an event listener like calling the setOnClickListener() method.

What is two-way binding in Android?

Two-way Data Binding is a technique of binding your objects to your XML layouts so that the layout can send data to your binding object. This is compared to a “traditional” or “one-way” Data Binding setup, where data would only move from your binding object to the layout.

What is one way data binding in Android?

Data binding in Android Updating the views from the data source is a simple one-way binding. In that case, you'll only access data from the data source and update the layout. Two-way data binding is nothing but updating the data source if there are any changes in the layout and vice versa.


6 Answers

Problem is @dimen/place_holder_size, it returns float while you are catching it as int

change you BindingAdapter method to this

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

}

you can refer this

like image 117
Ravi Avatar answered Oct 05 '22 15:10

Ravi


What I did wrong is the order of the arguments in the function. You can add multiple attributes in Binding Adapter, but they should match the arguments with the same sequence defined in the method.

Here is my code snippet for 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

    }
}
like image 25
Kishan Solanki Avatar answered Oct 05 '22 16:10

Kishan Solanki


try this

 @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);
        }
    }
like image 36
Nas Avatar answered Oct 05 '22 17:10

Nas


Update

You don't need to create prefix bind:, just use this.

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

}

In xml use any prefix like app:

app:url="@{image.imageUrl}"
like image 45
Khemraj Sharma Avatar answered Oct 05 '22 15:10

Khemraj Sharma


Apart from the example provided above by @Kishan Solanki, And with changes happening in the Data Binding library, all you need is to declare them with comma separated values. Example

@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)
    }

}

Bu the most important thing to remember is that you provide the data to the adapter attributes, in the DataBinding format.

example to provide Int as parameter in XML you have to write

app:widthDp="@{120}"

which is

app:your_attribute="@{your_data}"

P. S. - Oh and one more thing, widthDp**.px** is an extension function which converts Int of a dp value to relevant pixels value based on screen density. So don't get confused.

like image 31
sud007 Avatar answered Oct 05 '22 16:10

sud007


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

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

Note that BindingAdapter attributes and setImageUrl parameters may have different names. But they should go in the same order. If some of these attributes are defined in XML (in this example it is ImageView), this method will be called.

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

Attributes should have the same types as defined in the method. You can also use listeners. Instead of Kotlin lambdas use interfaces.

This class should be put in the same module with XML. Otherwise you will get an error like AAPT: error: attribute imageUrl (aka com.example.imageUrl) not found..

like image 32
CoolMind Avatar answered Oct 05 '22 15:10

CoolMind