数据绑定错误: 找不到符号类

我开始使用 DataBinding功能。我面临的问题与它。

错误: (21,9)错误: 找不到符号类 联系人列表活动绑定

Gradle (模块: app)

apply plugin: 'com.android.application'


android {
compileSdkVersion 23
buildToolsVersion "23.0.2"


defaultConfig {
applicationId "com.letsnurture.ln_202.databindingdemo"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}


dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
}

联系人 ListActivity.java

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;


import com.letsnurture.ln_202.databindingdemo.model.Contact;


public class ContactListActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


ContactListActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_list);
Contact user = new Contact("Chintan Soni", "+91 9876543210");
binding.setContact(user);


//        setContentView(R.layout.activity_contact_list);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);


FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_contact_list, menu);
return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();


//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}


return super.onOptionsItemSelected(item);
}
}

Content _ contact _ list. 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"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.letsnurture.ln_202.databindingdemo.ContactListActivity"
tools:showIn="@layout/activity_contact_list">


<data>


<variable
name="user"
type="com.letsnurture.ln_202.databindingdemo.model.Contact" />
</data>


<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/activity_horizontal_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior">


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.contactName}"
tools:text="Name" />


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.contactNumber}"
tools:text="Number" />
</LinearLayout>
</layout>

Activity _ contact _ list. xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.letsnurture.ln_202.databindingdemo.ContactListActivity">


<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">


<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />


</android.support.design.widget.AppBarLayout>


<include layout="@layout/content_contact_list" />


<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />


</android.support.design.widget.CoordinatorLayout>
168802 次浏览

You need to declare and pass the binding in the activity layout, not in the included layout.

Example from the documentation:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/name"
bind:user="@{user}"/>
<include layout="@layout/contact"
bind:user="@{user}"/>
</LinearLayout>
</layout>

Here, there must be a user variable in both the name.xml and contact.xml layout files.

You must change your activity_contact_list to be binded - add layout tag as you did in content_contact_list. Don't forget, The root layout inside activity_contact_list must have an id for the Binding class to be generated and will be named ActivityContactListBinding (i.e. the name of the layout with camel casting instead of underscores).

Next, inside activity_contact_list, give <include layout="@layout/content_contact_list" /> an id, then you will have access for its binding instance through your ActivityContactListBinding instance.

Somthing like:

binding.contentContactList.setContact(user);

Let me know if it works.

I consistently run into this problem. I believe it has to do with android studio not being aware of dynamically generated files. If you have everything else right for databinding try to File > Invalidate Caches/Restart... and select Invalidate Caches and Restart. Then try and import the BR file... it should import fine.

You may have to throw in a Clean and Rebuild.

this is your code

ContactListActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_list);

Replace this code

ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_contact_list);

Please refer to the android developer guide

Layout file was main_activity.xml so the generate class was MainActivityBinding

Since your xml is named "activity_contact_list.xml", you should use ActivityContactListBinding instead of the original one

I fell into this issue because my Activity was called MainActivityMVVM and the Binding was converted into MainActivityMvvmBinding instead of MainActivityMVVMBinding. After digging into the generated classes I found the issue.

Make sure the name for your model and the reference have the same name:

For example, name="item" must match android:checked="@={item.checked}"

<data>
<variable
name="item"
type="com.simone.mywordlist.model.MyModel" />
</data>


<Switch
android:id="@+id/my_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="@={item.checked}"
/>

I have got the same error, but with Kotlin usage.

To resolve it, i make some changes in gradles files :

In project's Gradle file :

dependencies {
classpath "com.android.tools.build:gradle:3.1.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.40"
}

In app's Gradle file :

dependencies {


...
implementation "android.arch.lifecycle:extensions:1.1.1"
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.30"
kapt 'com.android.databinding:compiler:3.1.2'
}




kapt {
generateStubs = true
}


//used to resolve annotation conflicts
configurations.all {
resolutionStrategy {
force 'com.android.support:support-annotations:23.1.1'
}
}

Keypoint

Your layout name is in snake_case.

activity_login.xml

Then your binding class name will be in CamelCase.

ActivityLoginBinding.java

Also build project after creating layout. Sometimes it is not generated automatically.

You can see Main Answer for complete information about data binding errors and solutions. I will try to tell some important points below.

5 Tips that I use to solve binding issues.

Assuming that you have enabled data binding in build.gradle and you have converted your layout to binding layout.

First of all binding class auto generate when you convert layout to binding layout. Still sometimes it is not generated when background threads are not working. Here are some tips for you to resolve this.

(1) Name of generated class

Layout name is in snake_case activity_main.xml

Data binding class will be in PascalCase like ActivityMainBinding.

(2). Type full name of Binding class

I felt sometimes when you type ActivityMai..., then it does not show suggestion, but that does not mean class is not generated. In that case you should type full name of expected generated class. Like type ActivityMainBinding and it will show import popup. (That's what i faced many times.)

Still not getting import suggestion. Try manual import.

import <yourpackage>databinding.ActivityMainBinding;

(3). Rebuild Project

If still your class is not generated. (Some time when we paste layout file, then it happens). Then Rebuild Project from Build> Rebuild (Not Build or Make project). It will generate your data binding class. (Rebuild does Magic for me all times.)

(4) If you have created an <variable in your layout and it does not show up its setter and getter in data binding class, then follow 4th point.

(5) Still if your class is not generating then you should check if build is not failing due to an error in your layout file. Data binding class will generate with a successful build.

This is all what i do to solve my data binding errors. If you get any further issue, you can comment here.

Source answer

In my case, there was a package with the same name as a missing import in the generated databinding class.. It seems like the compiler got confused.

Sometimes the reason of these errors are not the DataBinding itself, but some other part of our code. In my case I had an error in Room database so the compiler couldn't generate the binding classes and it gives me these errors.

According to Google:

Previous versions of the data binding compiler generated the binding classes in the same step that compiles your managed code. If your managed code fails to compile, you might get multiple errors reporting that the binding classes aren't found. The new data binding compiler prevents these errors by generating the binding classes before the managed compiler builds your app.

So to enable new data binding compiler, add the following option to your gradle.properties file:

android.databinding.enableV2=true

You can also enable the new compiler in your gradle command by adding the following parameter:

-Pandroid.databinding.enableV2=true

Note that the new compiler in Android Studio version 3.2 is enabled by default.

Improper package names can also cause the above error. As of Android Gradle plugin 3.2 (as far as I can tell) CamelCase package names will be inferred improperly as classes, which will break the generated binding object.

Example:

src
|
-> FooPackage
|
-> Bar.java

will be generated wrongly as

import src.FooPackage


...


public abstract class MyBinding extends ViewDataBinding {
@NonNull
public final FooPackage.Bar mInstance;
...
}

This obviously doesn't make any sense.

Refactor FooPackage to foopackage according to java conventions and be saved. You will then get:

import src.foopackage.Bar


...


public abstract class MyBinding extends ViewDataBinding {
@NonNull
public final Bar mInstance;
...
}

Just remove "build" folder in youy project directory and compile again, i hope it works for you too

You need to add the tags into your Activity's Xml Layout.

<?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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name=""
type="" />
</data
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.letsnurture.ln_202.databindingdemo.ContactListActivity">


</android.support.design.widget.CoordinatorLayout>
</layout>

and then, add an android:id into your tag

After that, you'll have a ActivityContactListBinding object and you can access and bind variables on your included layouts.

This problem may be occur when there is problem in layout file. In my case I just use wrong way to call method

android:onClick="@={() -> viewModel.showText()}"

instead of

  android:onClick="@{() -> viewModel.showText()}"

In my case I had the same issue but the reason was different. My onClick function was declared private in the activity class, so be sure that, if you are using a handler function inside the layout, the function must not be private.

// this will not be visible in the binded layout because it's private!
private fun mainButtonClick(view: View) {
if (viewModel.isRecording.value == true) {
stopRecordingAndPlaying()
} else {
startRecordingAndPlaying()
}
}

Don't forget to add in app level gradle, apply plugin: 'kotlin-kapt'

your model just have getter and setter in androidX. else not find your model in view and show this bug

public class User {


String name;


public String getName() {
return name;
}
public User(String name) {
this.name = name;
}

}

I have got the same issue and I found that variable name and method were missing. Double check the layout file or look for build error that says DATABINDINGISSUE, or invalidate and restart android studio. It should work.

In my project it was a trouble in:

android:text="@{safeUnbox(viewmodel.population)}"

So I've wrapped it in String.valueOf() :

android:text="@{String.valueOf(safeUnbox(viewmodel.population))}"

And it was resolved

I was calling my onClick wrong, which caused this error. So I changed

android:onClick="@{listener.onDogClicked()}"

to

android:onClick="@{listener::onDogClicked}"

For me it was an error in the layout xml binding, I had

app:setNameString="@{person}"

instead of

app:nameString="@{person}"

the type name must match the name you have set up in the @BindingAdapter class (if you are using binding adapter)

After ensuring the naming conventions are correct as described in other answers, and also trying to invalidate the cache and restart, deleting temp/cache folders the issue still persisted for me.

I got rid of it as follows: Add a new dummy XML resource. This will trigger bindings and its meta-data to re-create across the project. The annoying compile errors should no longer be visible anymore. You now delete the dummy XML you added.

For me as of August 2020, the Binding would automatically get corrupted repeatedly. It seems to be biting more than it can chew under the hood.

Actually it can be happend for various reason and for poor logging mechanism in data binding it is very hard to find the reason.So go got the proper error first go to the terminal and run the following command-

gradlew :app:build --stacktrace

It will show you the proper error with the number of line in XML where error is found.

For example -

ERROR: Could not find accessor com.example.model file://app\src\main\res\layout\fragment_example.xml Line:91

Your problem might actually be on this line:

<include layout="@layout/content_contact_list" />

Android Studio gets a little confused at time and takes the include layout for the layout tag. What's even more frustrating is that this could work the first time, fails to work with a modification on the Java/Kotlin code later, and then work again after a tweak that forces it to rebuild the binding. You may want to replace <include> tags with something that populates it dynamically.

make all your packages name's in the project that you used in binding to lower case.

You need to check your layout file, this error occurs due to the wrong use of data binding expression i.e you may not using proper syntax

I had faced the same issue when i try this without viewBinding

  buildFeatures {
dataBinding true
}

this will give that error while enabling view binding everything to work properly

  buildFeatures {
dataBinding true
viewBinding true
}

If you have changed your object package location and you forgot to update it import info into xml, that error can be occurred. Please check your object package location and its xml import package location.

In my case, I was putting onClick function to call asynchronous/suspend function which gave me an error cannot find a symbol class ... impl.

.xml file

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


<data>
<variable
name="dataFragment"
type="com.example.todoapp.fragment.SubmissionFragment" />
</data>
    

<Button
android:id="@+id/keepBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:onClick="@{() -> dataFragment.submit()}"
android:text="Add" />
</layout>

.fragment file

private lateinit val stringList: List<String>


...


suspend fun submit() {
dataDao.insert(stringList)
val action = SubmissionFragmentDirections.actionSubmissionFragmentToTodoFragment()
findNavController().navigate(action)
}

Then I replace Async Method with Launch Method by removing suspend function and insert viewModelScope.launch

fun submit() {
viewModelScope.launch {
dataDao.insert(stringList)
}


val action = SubmissionFragmentDirections.actionSubmissionFragmentToTodoFragment()
findNavController().navigate(action)
}

reference: https://www.geeksforgeeks.org/launch-vs-async-in-kotlin-coroutines/

Maybe you use the Same id in Layout widgets