Listener Binding; Cannot Find the Setter

2020-02-10 11:06发布

问题:

I am trying to implement listener bindings, but when I run my code I get the following error:

Caused by: android.databinding.tool.util.LoggedErrorException: Found data binding errors.
****/ data binding error ****msg:Cannot find the setter for attribute 'android:onClick' with parameter type lambda on android.widget.Button. file:~/GithubBrowser/app/src/main/res/layout/loading_state.xml loc:30:31 - 30:52 ****\ data binding error ****

This is the layout file in question:

<?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>
        <import type="com.example.app.data.model.Resource"/>
        <import type="com.example.app.data.model.Status"/>
        <variable name="resource" type="Resource"/>
        <variable name="callback" type="com.example.app.ui.common.RetryCallback"/>
    </data>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center"
        android:padding="@dimen/default_margin">

        <Button android:id="@+id/retry"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/retry"
            android:onClick="@{() -> callback.retry()}"/>

    </LinearLayout>

</layout>

And this is the RetryCallback interface referenced in the layout:

package com.example.app.ui.common

interface RetryCallback {

    fun retry()

}

Edit

The top-level build.gradle:

buildscript {
    ext.android_tools_version = '3.0.0-alpha3'
    ext.kotlin_version = '1.1.2-5'
    repositories {
        maven { url 'https://maven.google.com' }
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:$android_tools_version"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

ext {
    architecture_version = '1.0.0-alpha2'
    constraint_version = '1.0.2'
    dagger_version = '2.11'
    espresso_version = '2.2.2'
    glide_version = '3.7.0'
    junit_version = '4.12'
    mockito_version = '2.7.19'
    mock_server_version = '3.6.0'
    moshi_version = '1.5.0'
    retrofit_version = '2.2.0'
    support_version = '25.4.0'
    timber_version = '4.5.1'
}

allprojects {
    repositories {
        jcenter()
        mavenCentral()
        maven { url 'https://maven.google.com' }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

And the app module build.gradle:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.example.app"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        debug {
            testCoverageEnabled !project.hasProperty('android.injected.invoked.from.ide')
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    dataBinding {
        enabled = true
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

kapt {
    generateStubs = true
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

    compile "com.android.support:appcompat-v7:$support_version"
    compile "com.android.support:cardview-v7:$support_version"
    compile "com.android.support:design:$support_version"
    compile "com.android.support:recyclerview-v7:$support_version"
    compile "com.android.support.constraint:constraint-layout:$constraint_version"

    compile "android.arch.lifecycle:extensions:$architecture_version"
    compile "android.arch.lifecycle:runtime:$architecture_version"
    compile "android.arch.persistence.room:runtime:$architecture_version"

    compile "com.google.dagger:dagger:$dagger_version"
    compile "com.google.dagger:dagger-android:$dagger_version"
    compile "com.google.dagger:dagger-android-support:$dagger_version"

    compile "com.squareup.moshi:moshi:$moshi_version"
    compile "com.squareup.retrofit2:retrofit:$retrofit_version"
    compile "com.squareup.retrofit2:converter-moshi:$retrofit_version"

    compile "com.github.bumptech.glide:glide:$glide_version"

    compile "com.jakewharton.timber:timber:$timber_version"

    kapt "com.android.databinding:compiler:$android_tools_version"
    kapt "com.google.dagger:dagger-android-processor:$dagger_version"
    kapt "com.google.dagger:dagger-compiler:$dagger_version"
    kapt "android.arch.persistence.room:compiler:$architecture_version"
    kapt "android.arch.lifecycle:compiler:$architecture_version"

    testCompile "junit:junit:$junit_version"
    testCompile "com.squareup.okhttp3:mockwebserver:$mock_server_version"
    testCompile ("android.arch.core:core-testing:$architecture_version", {
        exclude group: 'com.android.support', module: 'support-compat'
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.android.support', module: 'support-ccore-utils'
    })

    androidTestCompile "com.android.support:appcompat-v7:$support_version"
    androidTestCompile "com.android.support:cardview-v7:$support_version"
    androidTestCompile "com.android.support:design:$support_version"
    androidTestCompile "com.android.support:recyclerview-v7:$support_version"

    androidTestCompile ("com.android.support.test.espresso:espresso-core:$espresso_version", {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.google.code.findbugs', module: 'jsr305'
    })

    androidTestCompile ("com.android.support.test.espresso:espresso-contrib:$espresso_version", {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.google.code.findbugs', module: 'jsr305'
    })

    androidTestCompile "org.mockito:mockito-android:$mockito_version"
}

回答1:

I just had that issue and I have managed to solve it by deleting .idea, .gradle and gradle folders and let Android Studio recreate whole project from scratch from gradle files.



回答2:

Make sure apply plugin: 'kotlin-kapt' is in build.gradle.

If you are running in to this and no amount of rebuilding the project, deleting directories, clearing AS settings do anything. The IDE is fine without having it but the building fails.

It would be nice if android studio had better error messages for this.



回答3:

Just rebuild the project. It is probably because you did some refactoring



回答4:

Rebuilding project worked for me.

  • Rebuild project from Build>Rebuild
  • Fix issues if you get in build logs.
  • Rebuild project again from Build>Rebuild


回答5:

  1. Delete .gradle folder.
  2. Run the project.
  3. Clean the project.
  4. Run the project.

Work for me. If the order mix or miss , its not working for me.



回答6:

Valid case: This error is raised if you have an error in the xml file. First read carefully through the xml and if you find a problem fix it.

Invalid case: For me the issue was raised for a file that was already deleted from the project or the file was renamed and the databinding was referencing the old file.

I'm not sure how to get rid of the issue every time but I have a number of things that sometimes work and sometimes don't.

Fix number 1:

Running 'gradle wrapper' in the project root.

Fix number 2:

Android Studio Clean Project

Next delete these folders in the project root:

rm -rf .gradle/

rm -rf app/build/

rm -rf build

rm -rf gradle

rm -rf gradlew

Android Studio Invalidate and restart

Everything should be back to normal now.



回答7:

As suggested by all other fellow brothers, yes the error resolves after deleting .idea, .gradle and gradle folders.

(this is just for someone curious why this happens, below is my usecase): i think this problem caused in my project because of i added one rxRecycleViewDataBinding custom library lately which might caused some binding errors by mixing binding references.



回答8:

If a similar kind of problem is encountered for a member variable of type LiveData then check your lambda in the XML file as for calling a function in onClick of a view "@{() -> variableName.callMethod()}" is used whereas for a variable "@{variableName.memeberVariableName}" is used.



回答9:

The error Cannot find the setter for attribute means, it cannot find setter method that accepts the variable of the data type you provided as a parameter for that attribute.

That means it won't find the BindingAdapter method that you have defined. I had this issue because I was providing a wrong data type in XML layout to a custom attribute that I defined using BindingAdapter. Once I gave the correct data type to the custom attribute, it worked.

So, check if you are providing correct data type to the custom attributes that you may have defined using BindingAdapters.