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

7.1k Views Asked by At

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 ?!

5

There are 5 best solutions below

0
Hussien Fahmy On BEST ANSWER

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" />
12
klim On

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>
8
Zain On

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

    }
}
1
Muzammil Hussain On

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}"
    
0
GauravDevMobile On

I also faced similar type of problem as mentioned in title. I was trying to change the visibility via data binding for <include> tag layout, like this:

<include
            android:id="@+id/viewNoData"
            layout="@layout/layout_no_data"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/quickActionRv"
            android:visibility="@{case== Case.NoData? View.VISIBLE : View.GONE}
            />

The solution was that I had to wrap my sublayout layout_no_data with

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

    </data>
Your content layout
</layout>

Hope it will help someone.