Класс привязки данных не создан

101

Я использую привязку данных в своем проекте, когда я использую <layout>и <data>в моем классе привязки xml не создается.

Например, у меня есть activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>    </data>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </RelativeLayout>
</layout>

Теперь, если я пишу ActivityMainBindingв своей активности / фрагменте, это показывает ошибку, что класс недоступен. Но после включения <variable>в мой XML-файл он может сгенерировать ActivityMainBindingкласс.

Android Studio: 2.1.3 Путь к классам
: com.android.tools.build:gradle:2.1.3
minSdkVersion 16
targetSdkVersion 24
buildToolsVersion 24.0.0

Рави
источник
2
есть dataBinding.enabledв вашем build.gradle?
pskink
2
Думаю, это известная ошибка. Вы можете попробовать собрать свой проект, прежде чем пытаться получить доступ ActivityMainBinding, или он должен что-то делать с этой ошибкой.
yennsarah
@pskink да, именно поэтому он генерирует класс привязки после добавления <variable>в xml
Рави
@Amylinn после создания моего проекта он генерирует, но мой вопрос в том, что когда я пишу <variable>, он генерирует класс привязки без создания проекта.
Рави
1
Я не понимаю, в чем заключается реальный вопрос? если добавление <variable> может решить проблему, почему бы вам этого не сделать? Я не понимаю точки привязки без ViewModel (<variable>)
ktutnik

Ответы:

228

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

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

Обновить

Чтобы получать более точные ошибки и предложения , я настоятельно рекомендую обновить версию плагина Android Studio и Gradle до последней. Потому что после версии AS 3.2 у меня не так много проблем.

Смотрите последнюю версию Android Studio и последний плагин Gradle .

Оригинальное решение

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

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

1. Проверьте, включена ли привязка данных.

У вас должна быть включена привязка данных в build.gradle. Если нет, добавьте это и синхронизируйте .

android {
...
   dataBinding {
        enabled = true
    }
...
}

2. Макет чека преобразован в макет переплета.

Теперь, если вы хотите, чтобы был сгенерирован класс привязки данных, вам следует обернуть его xml layoutпривязкой данных ( <layoutтегом). Что-то вроде этого.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.constraint.ConstraintLayout>
</layout>

Наряду с этим проверьте правильность имен переменных привязки, как в классе модели представления.

3. Автоматически сгенерированное имя класса привязки?

Ваш класс привязки данных должен быть сгенерирован после создания макета привязки.

Если ваше имя макета указано в случае змеи, activity_main.xml тогда класс привязки данных будет создан в случае верблюда, например ActivityMainBinding.

4. Не видите предложения по импорту?

Иногда , когда вы печатаете ActivityMai..., то это не показывает предложение , в этом случае импорт вручную .

import <yourpackage>databinding.ActivityMainBinding;

5. Прочтите журнал ошибок сборки.

Ваш класс привязки и новые переменные в макете не будут созданы, если ваша сборка не удалась. Итак, сначала создайте проект с помощью Ctrl + F9 (Сборка> Создать проект) .

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

6. Закройте и откройте проект из недавнего

Я всегда так делаю, потому что это занимает гораздо меньше времени, чем Rebuild/ Makeproject.

  • Закройте проект из файла> Закрыть проект
  • Открыть снова из недавних

Обратите внимание, что я предпочитаю Close и Open from Recent, потому что это занимает гораздо меньше времени, чем Rebuild / Restart IDE .

7. Восстановить проект

Если по-прежнему ваш класс не сгенерирован. (Иногда, когда мы вставляем файл макета, это происходит). Затем перестройте проект из Build> Rebuildне сборку или создание проекта ). Он сгенерирует ваш класс привязки данных. ( Rebuild делает за меня Magic. )

8. Установите последнюю версию Android Studio.

После обновления AS до Android Studio 3.2 я почувствовал, что исправлено много ошибок в автогенерации привязки данных. Так что у вас также должна быть последняя версия AS.

Решение для <variables

<data>
    <variable
        name="item"
        type="com.package.Model"/>
</data>

Обычно, когда мы помещаем переменную в макет, он создает для нее геттер и сеттер. И мы можем использовать binding.setItem(item);и binding.getItem();, но если вы не видите эти методы, прочтите информацию ниже.

1. Закройте и откройте проект из недавнего

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

2. Очистите проект после изменения типа

Если вы изменили тип некоторых <variableв своем макете и тип установщика геттера не меняется, тогда Clean project ( Build> Clean Project)

Заключительные слова

Наконец, если ваш класс привязки по-прежнему не сгенерирован, значит, у нас есть самое мощное оружие. - Перезагрузите Android Studio: D

  • Сначала попробуйте просто перезапустить , это всегда генерирует переменные моего макета привязки после перезапуска.
  • Если это не сработает, сделайте недействительный кеш и перезапустите .

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

Хемрадж
источник
2
Если проблема не исчезнет ... (8) Сделать недействительным и перезапустить .... если не решить, (9) изменить dataBinding {enabled = false} ... build, а затем dataBinding {enabled = true} построить снова ....
PravyNandas
1
В моем случае мне пришлось вручную импортировать путь к классам, по какой-то причине IDE не показывает это как решение. Tnx :)
Иван Калоянов
2
Спас мой день. Мне не хватало обертки <layout> в моем файле макета. Спасибо!
Джулиано
Вы также можете добавить, что "import android.R" должен быть удален, если он входит в список импорта. Это решило мою проблему с неразрешенной ссылкой на XML-файл активности
Тим Джон
23

Класс DataBinding создается автоматически.

если ваше имя xml - activity_test, тогда класс привязки будет ActivityTestBinding.

но,

dataBinding {
        enabled = true
    }

макет должен иметь макет как корневой

<layout xmlns:android="http://schemas.android.com/apk/res/android">
</layout>
Вирамп
источник
Я часами ищу soultion, много занимаюсь магией gradle, но использую ConstraintLayoutкак root. Спасибо!
Алексей Марков
14

Я была такая же проблема. После прочтения документации android sdk создается только ожидаемое имя файла, но ничего о том, что делать, если этого не происходит. После еще нескольких исследований я заметил, что после удаления пространства имен для элемента макета, как показано ниже (используя ваш пример), это сработало для меня.

    <?xml version="1.0" encoding="utf-8"?>
    <layout>
        <data>  </data>
        <RelativeLayout
           xmlns:android="http://schemas.android.com/apk/res/android"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
        </RelativeLayout>
    </layout> 
нгаспама
источник
10

В моем случае класс Binding был сгенерирован и на месте (но я думал, что это не так) ... но он не добавляет автоматически импорт указанного класса в раздел импорта активности / фрагмента ... так что ... OPTION + ВОЙТИ :)

Кшиштоф Кубицки
источник
2
Бинго работал у меня, хотя мне приходилось вводить импорт вручную, intellisense не предлагал эту возможность по какой-либо причине.
Роб
8

После правильной настройки (включая пространство имен xml и упаковку всего в него <layout>), тот, который работал у меня, выполнял Build -> Make project. Ни Clean Project, ни Rebuild Project не сделали. Я в Android Studio 2.3.1, использую инструменты сборки 26.0.2. <data>Теги не нужны .

Экстремальный байкер
источник
Это должно быть отмечено как правильный ответ. Остальные - всего лишь обходные пути. Нет необходимости перемещать пространства имен или даже добавлять элементы данных
Вики Кападиа
8

если вы выполняете базовую работу, для включения базы данных в своем проекте, например, используйте enable в gradle и используйте тег макета в xml , когда вы меняете xml-код и не генерируете новый класс привязки данных для этих xml, вы можете использовать быстрый способ для генерации только данных класс привязки в gradle-> other-> databindinggenbaseclasses Отлаживайте его быстрее, чем весь проект. он генерирует только класс привязки данных. введите описание изображения здесь

Махди Азадбар
источник
4
dataBinding {
        enabled = true
    }

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

android.databinding.enableV2=true
Самир Мангролия
источник
3

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

Злорадство
источник
2

Не знаю, подойдет он вам или нет. Просто переименуйте XML-файл макета. Например, предположим, что ваше имя макета - activity_main.xml, просто измените его, переименуйте на что-нибудь вроде main.xml и снова переименуйте его в activity_main.xml . Затем вы сможете увидеть параметр импорта в ActivityMainBinding .

Надеюсь, это сработает для вас.

Судхансу
источник
2

Благодаря этому ответу здесь - похоже, что «пространство имен макета» нужно либо очистить, либо вам нужно новое уникальное имя.

Вот варианты, которые у меня сработали:

  1. Создайте новое имя для макета, чтобы его можно было сгенерировать. Это решило мою проблему, когда у меня был первый созданный макет без привязки данных - назовем его fragment_abc.xml. Когда я попытался добавить к нему привязку данных, он не был распознан - даже после нескольких вызовов очистки кеша и перезапуска. Однако как только я сделал копию макета fragment_abc2.xml, сразу же получил сгенерированный объект привязки данных .java / .class.

  2. Увидев вышеуказанную работу, я попытался просто удалить папку / build из модуля и перестроить проект - это помогло получить привязку данных для исходного макета.

Джин Бо
источник
1

Единственное, что я могу представить, если это возможно, - это если у вас нет

dataBinding {
    enabled true
}

в вашем файле gradle. Если не просто добавить его в файл gradle. т.е.

android {
  ......

  dataBinding {
    enabled true
  }
}

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

Хасан Семиу Айомон
источник
Я четко упомянул в своем вопросе, что после добавления <variable>в xml он создает класс dataBindingпривязки , поэтому нет случая не добавлять в файл gradle, если я не добавил, то он не должен создавать класс привязки.
Рави
Перед синхронизацией и перезапуском. Пожалуйста, попробуйте «Сделать». Это будет тренировка.
Низамудин Шериф
1

Когда вы работаете с многомодульным Android-приложением, проверьте свой путь к классу привязки. Возможно, вам стоит использовать:

import com.yourcompany.app.android.modulename.databinding.FragmentABCtBinding insted из:

import com.yourcompany.app.android.databinding.FragmentABCtBinding

Косиара - Бартош Косаржицкий
источник
1

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

Ахмед Аль-Аскалани
источник
1

Мое решение заключалось в том, чтобы использовать суффикс FragmentBinding в имени класса.

Для каждого файла макета создается класс привязки. По умолчанию имя класса основывается на имени файла макета, преобразовывая его в регистр Паскаля и добавляя к нему суффикс Binding. Указанное выше имя файла макета - activity_main.xml, поэтому соответствующий сгенерированный класс - ActivityMainBinding. Этот класс содержит все привязки от свойств макета (например, пользовательской переменной) к представлениям макета и знает, как назначать значения для выражений привязки.

Номенклатура имени класса активности или фрагмента может варьироваться в зависимости от префиксов. Потому что суффикс всегда Binding.

После выполнения реакции Khemraj и Invalidate кэширует / Restart , вы должны переписать ActivityBinding или FragmentBinding , чтобы получить IDE предложения классов , которые уже были сгенерированы и НЕ жёстко импорт.

В моем случае я пытался импортировать имя класса в обратном порядке FragmentCompetitionsBindingвместо CompetitionsFragmentBinding.

GL

Источник

Брайан Коронел
источник
1

Если ответ не помог вам, то моя рекомендация проста, но эффективна.

Идея состоит в том, чтобы определить, какой компонент является причиной проблемы. Для этого прокомментируйте все строки вашего custom_fragment.xmlи его использования в CustomFragment.ktи оставьте что-нибудь минималистичное, например следующее.

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

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</layout>

Затем запустите приложение и добавьте компонент в компонент, пока вы Apply Code Changes(Ctrl + Alt + F10) выполняете приложение, пока приложение не выйдет из строя, то есть когда вы обнаружили ошибку.

Журналы привязки данных иногда не столь информативны, и это общая стратегия поиска неисправного компонента.

GL

Брайан Коронел
источник
0

У меня была такая же проблема. Вы все сделали правильно. Дело в том, что вам нужно добавить переменную внутри тега данных в xml. Для этого вы должны создать образец класса модели и добавить его как переменную в теге данных.

До этого вы не увидите сгенерированного ActivityMainBinding.

Шринивасан
источник
0

У меня была аналогичная проблема, когда у меня был обернут макет и включена привязка данных в файле gradle. Основная деятельность по-прежнему не может быть intellisense или видеть мои классы. Для меня это исправило добавление переменной привязки и импорт привязки в любом случае. Оттуда я просто построил решение, а потом, похоже, он узнал, что это за класс. Оттуда я смог импортировать свои созданные классы случаев верблюда.

Stegnerd
источник
0

У меня возникла проблема, и проблема заключалась в макете, используемое поле не было строкой, это была дата.

Похоже, что для работы все поля должны быть текстовыми, по крайней мере, с компонентом TexView.

Если вы строите с помощью команды ./gradlew build --stacktrace

Это лучше показывает ошибки.

активный
источник
0

В моем случае я думал, что сгенерированный класс должен появиться вместе с моими обычными классами в srcпапке. Вдобавок я подумал, что имя сгенерированного класса должно немного отличаться. Все это было моей ошибкой. Сгенерированный класс можно найти в buildпапке по build -> generated -> ...пути. Если в вашей деятельности нет импорта сгенерированного класса, добавьте импорт

import com.yourcompany.app.databinding.ActivityMainBinding;"
Ксения
источник
0

Если вы получаете следующую ошибку в DataBindingUtil.setContentView

Неразрешенная ссылка: activity_main

все, что вам нужно сделать, это удалить следующий оператор импорта

импортировать android.R

Я нашел решение на другом форуме. Источник

Тим Джон
источник
0

Если недавно какой-либо из существующих проектов перенесен в androidx, вам необходимо заменить импорт из

import com.yourpackagename.BR;

к

import androidx.databinding.library.baseAdapters.BR;

Через 2 дня Google наконец получил решение, которое работает для меня.

Милан Шет
источник
1
Нет. Привязка ресурса ( .BR. ) Как Resource ( .R. ). Он сгенерирован на основе вашего ресурса проекта (id, drawable, color, ...), поэтому он будет размещен внутри вашего проекта package ( your.project.package.BR). Не внутри сторонней библиотеки, например androidx.databinding.library.baseAdapters.BR.
dphans 02
0

Бывают случаи, когда вы не видите файл в сгенерированном каталоге, возможно, вы привязываете свойство, которое не объявлено в viewmodel. По сути, это не дает вам ошибки lint, если вы делаете это в xml.

Узаир
источник
0

Если вы реализуете Serializable ->, вы должны реализовать Serializable

иначе вы получите эту ошибку. Надеюсь, это поможет кому-то в будущем

В моем случае я использую библиотеку Parcel. Я пропустил аннотирование @Parcel в моем подклассе

Ранджит Кумар
источник
0

В дополнение к вышеуказанным шагам вы также можете проверить тип переменной. Убедитесь, что это String для TextView или то же, что определено в BindingAdapter. Например:

data class MyDataObject(val name: String, val age: Int)

и в XML:

android:text="@{dataobject.age}"

Это вызовет указанную выше ошибку. Чтобы исправить это, вы можете либо сделать переменную возраста типа String, либо импортировать String в свой XML и использовать String.valueOf(age)следующее:

<data>
    <import type="String" />
...
</data>

И в вашем TextView:

android:text="@{String.valueOf(dataobject.age)}"
Шьям
источник
0

В моем случае классы привязки данных не были созданы, потому что я удалил каталог ресурсов Android mipmap. Я воссоздал каталог res / mipmap /, и классы привязки данных были восстановлены.

неуклюже
источник
0

Я столкнулся с аналогичной проблемой, когда DataBinding не удалось создать класс BindingImpl . В моем случае проблема была связана с методом в классе данных, где имя было использовано неправильно: модель содержала метод onSignInCliked (), а в макете, который я использовал, onSigninCliked () . Обратите внимание на вход в систему и вход в систему .

Сообщения об ошибке было недостаточно, и я обнаружил проблему только тогда, когда использовал сценарий сборки с параметром трассировки стека.

Ионут Негру
источник
0

Убедитесь, что привязка данных включена

android {
...
   dataBinding {
        enabled = true
    }
...
}

Синхронизировать проект с Gradle Дан нажмите кнопку (Синхронизировать проект с Gradle)

fahrizal89
источник
0

Если есть проблема с вашим XML-файлом, класс Databinding не будет создан. Быстрое исправление - просмотреть XML-файл и проверить синтаксические ошибки (которые обычно выделяются красным). Ошибки могут быть в виде несуществующих или неправильных ссылок, типографских ошибок и т. Д.

По сути, просто убедитесь, что в вашем XML-коде нет красной подчеркнутой строки. Когда вы закончите, перестройте, и ваш класс привязки данных будет создан.

Таслим Осени
источник
-1

1. добавить ниже в приложение gradle

 dataBinding {
        enabled = true
    }

2. В макете xml напишите ниже код

<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
  <data></data>
</layout>if you don't get data binding class just rename the layout file name and you will get data binding class.
Рохан Лодхи
источник
3
Почему dataBinding в общем случае требует разрешения в Интернете?
M.Pomeroy
1
@ M.Pomeroy да не требуется, не редактировал ответ спасибо
Рохан Лодхи
-5

используйте путь к классу 'com.android.databinding: dataBinder: 1.0-rc0'

Суманта Банерджи
источник
для gradle 1.5.0 и выше использовать этот путь к классам не требуется.
Рави