Android: ошибка привязки данных: не удается найти класс символов

Я начал использовать функцию DataBinding. Я столкнулся с проблемой.

Ошибка: (21, 9) ошибка: не удается найти класс символов ContactListActivityBinding

build.gradle(модуль: приложение)

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>

Ответ 1

это ваш код

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

Заменить этот код

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

Ответ 2

Я постоянно сталкиваюсь с этой проблемой. Я считаю, что это связано с тем, что андроидная студия не знает динамически сгенерированные файлы. Если у вас есть все, что нужно для привязки данных, попробуйте "Файл" > "Недействить кеши/перезапуск..." и выберите "Недействительные кеши и перезагрузите". Затем попробуйте импортировать файл BR... он должен импортировать штраф.

Возможно, вам придется бросить "Чистое" и "Восстановить".

Ответ 3

Пожалуйста, обратитесь к руководству разработчика Android

Файл макета был main_activity.xml, поэтому класс генерации был MainActivityBinding

Поскольку ваш XML файл называется "activity_contact_list.xml", вы должны использовать ActivityContactListBinding вместо исходного

Ответ 4

Вы можете увидеть Основной ответ для получения полной информации об ошибках привязки данных и решениях. Я постараюсь рассказать о некоторых важных моментах ниже.

5 советов, которые я использую для решения проблем связывания.

Предполагая, что у вас включена привязка данных в build.gradle, и вы преобразовали макет в макет привязки.

Прежде всего, класс связывания автоматически генерируется при преобразовании макета в макет привязки. Тем не менее иногда это не генерируется, когда фоновые потоки не работают. Вот несколько советов, которые помогут вам решить эту проблему.

(1) Name of generated class

Название макета находится в snake_case activity_main.xml

Класс привязки данных будет в PascalCase как ActivityMainBinding.

(2). Введите полное имя класса привязки

Иногда я чувствовал, что когда вы печатаете ActivityMai..., тогда не показывает подсказку, но это не означает, что класс не генерируется, В этом случае вы должны ввести полное имя ожидаемого сгенерированного класса. Например, введите ActivityMainBinding, и он покажет всплывающее окно импорта. (Это то, с чем я сталкивался много раз.)

Все еще не получаю предложение об импорте. Попробуйте ручной импорт.

import <yourpackage>databinding.ActivityMainBinding;

(3). Rebuild Project

Если ваш класс еще не создан. (Иногда, когда мы вставляем файл макета, это происходит). Затем Перестройте проект из Build> Rebuild (не "Создать или создать проект"). Это сгенерирует ваш класс привязки данных. (Перестройка всегда делает магию для меня.)

(4) Если вы создали <variable в своем макете, и он не отображает свои установщик и получатель в классе привязки данных, то следует за 4-м указать.

(5) Тем не менее, если ваш класс не генерирует, вам следует проверить, не сбилась ли сборка из-за ошибки в файле макета. Класс привязки данных будет создан при успешной сборке.

Это все, что я делаю, чтобы решить мои ошибки привязки данных. Если у вас возникнут дополнительные проблемы, вы можете оставить комментарий здесь.

Исходный ответ

Ответ 5

Вам необходимо объявить и передать привязку в макете активности, а не во включенном макете.

Пример из документации:

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

Здесь должна быть пользовательская переменная в файлах макетов name.xml и contact.xml.

Ответ 6

Неправильные имена пакетов также могут вызвать вышеуказанную ошибку. Начиная с плагина Android Gradle 3.2 (насколько я могу судить) имена пакетов CamelCase будут неверно выведены как classes, что нарушит сгенерированный объект привязки.

Пример:

src
|
-> FooPackage
    |
    -> Bar.java

будет сгенерировано неправильно как

import src.FooPackage

...

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

Это, очевидно, не имеет никакого смысла.

Преобразуйте FooPackage в foopackage в соответствии с Java-соглашениями и сохраните. Затем вы получите:

import src.foopackage.Bar

...

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

Ответ 7

Вы должны изменить свой activity_contact_list для привязки - добавить тег макета, как и в content_contact_list. Не забывайте, что корневая компоновка внутри activity_contact_list должна иметь идентификатор для класса Binding, который будет сгенерирован, и будет называться ActivityContactListBinding (то есть имя макета с литым верблюдом вместо подчеркивания).

Далее, внутри activity_contact_list, укажите <include layout="@layout/content_contact_list" /> идентификатор, тогда у вас будет доступ к экземпляру привязки через экземпляр ActivityContactListBinding.

Somthing like:

binding.contentContactList.setContact(user);

Сообщите мне, если он работает.

Ответ 8

Убедитесь, что имя для вашей модели и ссылки имеют одно и то же имя:

Например, name= "item" должен соответствовать андроиду: 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}"
            />

Ответ 9

У меня та же ошибка, но с использованием Kotlin.

Чтобы решить эту проблему, я внес некоторые изменения в файлы gradles:

В файле Gradle проекта:

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

В приложении Gradle файл:

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'
    }
}

Ответ 10

Эта проблема может возникнуть, когда есть проблема в файле макета. В моем случае я просто использую неправильный способ вызова метода

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

вместо

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

Ответ 11

Ключевой момент

Ваше имя макета находится в snake_case.

activity_login.xml

Тогда ваше имя связующего класса будет в CamelCase.

ActivityLoginBinding.java

Также соберите проект после создания макета. Иногда это не генерируется автоматически.

Ответ 12

Иногда причина этих ошибок не в самой DataBinding, а в какой-то другой части нашего кода. В моем случае у меня была ошибка в базе данных Room поэтому компилятор не смог сгенерировать классы привязки, и он выдает мне эти ошибки.

По данным Google:

Предыдущие версии компилятора привязки данных генерировали классы привязки на том же этапе, что и ваш управляемый код. Если ваш управляемый код не компилируется, вы можете получить несколько ошибок, сообщающих, что классы привязки не найдены. Новый компилятор привязки данных предотвращает эти ошибки, генерируя классы привязки до того, как управляемый компилятор создаст ваше приложение.

Поэтому, чтобы включить новый компилятор привязки данных, добавьте следующую опцию в ваш файл gradle.properties:

android.databinding.enableV2=true

Вы также можете включить новый компилятор в вашей команде gradle, добавив следующий параметр:

-Pandroid.databinding.enableV2=true

Обратите внимание, что новый компилятор в Android Studio версии 3.2 включен по умолчанию.

Ответ 13

Просто удалите папку "build" в директории проекта youy и снова скомпилируйте, надеюсь, она вам тоже подойдет

Ответ 14

Вам нужно добавить теги в макет Activity 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">
    <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>

а затем добавьте android: id в ваш тег

После этого у вас будет объект ActivityContactListBinding, и вы сможете получать доступ и связывать переменные во включенных макетах.

Ответ 15

Я попал в эту проблему, потому что моя активность называлась MainActivityMVVM, а привязка была преобразована в MainActivityMvvmBinding вместо MainActivityMvvmBinding. После поиска в сгенерированных классах я нашел проблему.

Ответ 16

В моем случае в сгенерированном классе привязки данных был пакет с тем же именем, что и у отсутствующего импорта. Кажется, что компилятор запутался.

Ответ 17

В моем случае была просто опечатка в использовании имени переменной. Я могу найти это в журналах.

Ответ 18

В моем случае у меня была та же проблема, но причина была в другом. Моя функция onClick была объявлена закрытой в классе активности, поэтому убедитесь, что, если вы используете функцию-обработчик внутри макета, функция не должна быть закрытой.

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

Ответ 19

Не забудьте добавить в приложение Gradle уровня, apply plugin: 'kotlin-kapt'

Ответ 20

В моем случае я использовал атрибут onClick как android: onClick = "@{viewModel.onClick()}"

и это было причиной ошибки