'Android Databinding Cannot find a setter for * that accepts parameter type *

Am trying to declare a variable in databinding layout it's type is array of integer but I getting an error when building the project

Cannot find a setter for <android.widget.LinearLayout app:availableGradesIndexes> that accepts parameter type 'int[]'

If a binding adapter provides the setter, check that the adapter is annotated correctly and that the parameter type matches.

the variable declaration in xml

<variable
    name="availableGradesIndexes"
    type="int[]" />

<variable
    name="subject"
    type="Subject" />

the binding adapter

@BindingAdapter("availableGradesIndexes", "subject")
fun LinearLayout.bindGradeWithMarks(availableGradesIndexes: Array<Int>) {
    //....
}

usage

<LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:subjct="@{subject}"
        app:availableGradesIndexes="@{availableGradesIndexes}"
        tools:layout_height="@dimen/_40sdp" />

What else I Tried

tried to declare the type of binding adapter method to IntArray like fun LinearLayout.bindGradeWithMarks(availableGradesIndexes: IntArray)

also tried a List<Int> like fun LinearLayout.bindGradeWithMarks(availableGradesIndexes: List<Int>) and variable type List&lt;Int&gt;

also tried the binding variable type to be Integer and Integer[] and also List&lt;Integer&gt;

so the question is how to bind a list or array of integer with binding adapter ?!



Solution 1:[1]

The problem was in another attribute name and I don't know why the error message didn't mention it !!

<LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:subjct="@{subject}" //the attribute name was messing a letter (subject)
        app:availableGradesIndexes="@{availableGradesIndexes}"
        tools:layout_height="@dimen/_40sdp" />

Solution 2:[2]

It is because Array<Int> in Kotlin is Integer[] in Java.
Try to use IntArray in Java it will be int[].

I tried your example with IntArray and it works.

@BindingAdapter("availableGradesIndexes")
fun LinearLayout.bindGradeWithMarks( availableGradesIndexes: IntArray ) {
}

Can you show your layout XML?

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="availableGradesIndexes"
            type="int[]" />
    </data>

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:availableGradesIndexes="@{availableGradesIndexes}"
        tools:layout_height="match_parent" />

</layout>

Solution 3:[3]

Instead of int[] you can use a List, but this requires to import the List class into the layout in order to be able to use it as a type for the availableGradesIndexes variable:

<data>

    <import type="java.util.List" />

    <variable
        name="availableGradesIndexes"
        type="List&lt;Integer&gt;" />
</data>

Then you can apply that to the BindingAdapter using a List<Int>:

@BindingAdapter("availableGradesIndexes")
fun LinearLayout.bindGradeWithMarks(availableGradesIndexes: List<Int>) {
    //....
    Log.d("LOG_TAG", "bindGradeWithMarks: $availableGradesIndexes") // For testing
}

If you want to use the int[] array; no imports are required:

<data>

    <variable
        name="availableGradesIndexes"
        type="int[]" />

</data>

And the adapter:

@BindingAdapter("availableGradesIndexes")
@JvmStatic
fun LinearLayout.bindGradeWithMarks(availableGradesIndexes: IntArray) {
    //....
    Log.d("LOG_TAG", "bindGradeWithMarks: ${availableGradesIndexes.toList()}")
}

UPDATE:

Cannot find a setter for <android.widget.LinearLayout app:availableGradesIndexes> that accepts parameter type 'java.util.List<java.lang.Integer>'

This means that the BidningAdapter method is not recognized in the layout; so just make sure to add it in a companion object, and annotated by @JvmStatic:

class BindingAdapters {

    companion object {
        @BindingAdapter("availableGradesIndexes")
        @JvmStatic
        fun LinearLayout.bindGradeWithMarks(availableGradesIndexes: List<Int>) {
            //....
            Log.d("LOG_TAG", "bindGradeWithMarks: $availableGradesIndexes")
        }

    }
}

Solution 4:[4]

In Kotlin Case:

  1. simply put your function in companion Object like this.

    companion object {
    @BindingAdapter(" app:availableGradesIndexes", "subject")
     @JvmStatic fun LinearLayout.bindGradeWithMarks(
       availableGradesIndexes: Array<Int>) {
      //....
    }
    }
    
  2. Make sure attributes should be same

    app:availableGradesIndexes="@{availableGradesIndexes}"
    

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Hussien Fahmy
Solution 2
Solution 3
Solution 4 Muzammil Hussain