android: data binding error: cannot find symbol class
AndroidAndroid DatabindingAndroid Problem Overview
I am getting started for using DataBinding
feature. I am facing problem with it.
> Error:(21, 9) error: cannot find symbol class > ContactListActivityBinding
build.gradle(Module: 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'
}
ContactListActivity.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>
Android Solutions
Solution 1 - Android
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.
Solution 2 - Android
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
Solution 3 - Android
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()}"
Solution 4 - Android
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
Solution 5 - Android
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
Solution 6 - Android
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;
...
}
Solution 7 - Android
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);
Solution 8 - Android
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.
Solution 9 - Android
I was calling my onClick
wrong, which caused this error. So I changed
android:onClick="@{listener.onDogClicked()}"
to
android:onClick="@{listener::onDogClicked}"
Solution 10 - Android
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}"
/>
Solution 11 - Android
Don't forget to add in app level gradle, apply plugin: 'kotlin-kapt'
Solution 12 - Android
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
Solution 13 - Android
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.
Solution 14 - Android
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'
}
}
Solution 15 - Android
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.
Solution 16 - Android
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()
}
}
Solution 17 - Android
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.
Solution 18 - Android
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
Solution 19 - Android
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.
Solution 20 - Android
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.
Solution 21 - Android
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.
Solution 22 - Android
Just remove "build" folder in youy project directory and compile again, i hope it works for you too
Solution 23 - Android
You need to add the
<?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
After that, you'll have a ActivityContactListBinding object and you can access and bind variables on your included layouts.
Solution 24 - Android
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)
Solution 25 - Android
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.
Solution 26 - Android
make all your packages name's in the project that you used in binding to lower case.
Solution 27 - Android
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
}
Solution 28 - Android
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.
Solution 29 - Android
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;
}
}
Solution 30 - Android
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.
Solution 31 - Android
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/