Classe de vinculação de dados não gerada

96

Estou usando Data Binding em meu projeto, ao usar <layout>e <data>em minha classe de vinculação xml não é gerada.

Por exemplo, eu tenho 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>

Agora, se estou escrevendo ActivityMainBindingna minha atividade / fragmento, mostra um erro que a classe não está disponível. Mas depois de incluir <variable>no meu arquivo xml, ele é capaz de gerar ActivityMainBindingclasse.

Android Studio: 2.1.3
Classpath: com.android.tools.build:gradle:2.1.3
minSdkVersion 16
targetSdkVersion 24
buildToolsVersion 24.0.0

Ravi
fonte
2
está dataBinding.enabledem seu build.gradle?
pskink
2
Acho que é um erro conhecido. Você pode tentar construir seu projeto antes de tentar acessá ActivityMainBinding-lo, ou ele tem que fazer algo com este bug.
yennsarah
@pskink sim, é por isso que está gerando classe de ligação após adicionar <variable>em xml
Ravi
@Amylinn depois de construir meu projeto ele gera, mas minha dúvida é quando eu escrevo <variable>, ele gera classe de ligação sem construir projeto.
Ravi de
ah, de fato, eu perdi isso
pskink

Respostas:

214

Não obtive respostas satisfatórias. Portanto, aqui estão as dicas que são um resumo do meu conhecimento de vinculação de dados.

Dicas para resolver problemas de DataBinding

Atualizar

Para obter erros e sugestões mais precisos , recomendo fortemente atualizar o Android Studio e a versão do plugin do Gradle para a versão mais recente. Porque não estou enfrentando muitos problemas após a versão AS 3.2.

Consulte o mais recente Android Studio e o mais recente plug-in do Gradle .

Solução Orignal

Depois de ler esta resposta, você não ficará preso a problemas de geração automática de vinculação de dados para classes e variáveis ​​de dados .

Verifique esses pontos um por um. Qualquer um deles pode fazer seu trabalho. O ponto 3 ao final é muito importante, por isso não os perca.

1. Verifique se a vinculação de dados está ativada

Você deve ter a vinculação de dados ativada em build.gradle. Se não, adicione isso e sincronize .

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

2. Verifique se o layout é convertido em layout de ligação

Agora, se você deseja que a classe de ligação de dados seja gerada, você deve envolver xml layoutcom a ligação de dados ( <layouttag). Algo assim.

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

Junto com isso, verifique se os nomes das variáveis ​​de ligação estão corretos como na classe do modelo de visualização

3. Nome da classe de vinculação gerado automaticamente?

Sua classe de ligação de dados deve ser gerada após a criação do layout de ligação.

Se o seu nome layout é no caso de cobra activity_main.xml , em seguida, classe de ligação de dados será gerado no caso de camelo como ActivityMainBinding.

4. Não consegue ver a sugestão de importação?

Às vezes, ao digitar ActivityMai..., não há sugestão , nesse caso importe manualmente .

import <yourpackage>databinding.ActivityMainBinding;

5. Leia Build Fail Logcat

Sua classe de ligação e novas variáveis ​​no layout não serão geradas se sua construção falhar. Portanto, primeiro faça o projeto com Ctrl + F9 (Build> Make project) .

  • Se uma construção falhar, veja o que é um erro, geralmente temos erros nos campos de layout. Os logs de erros indicarão o número da linha de erro com o problema.
  • A vinculação pode falhar e causar algum erro estúpido , como erro de sintaxe ou importação ausente. Nesse caso, você obterá o logcat cheio de erros de classes de ligação. Mas você deve ler o logcat completo para encontrar o problema apropriado .

6. Feche e abra o projeto do recente

Sempre faço isso porque leva muito menos tempo do que Rebuild/ Makeproject.

  • Fechar projeto em Arquivo> Fechar Projeto
  • Abra novamente a partir do recente

Observe que eu prefiro Fechar e Abrir do Recente porque leva muito menos tempo do que Reconstruir / Reiniciar IDE .

7. Projeto de reconstrução

Se ainda assim sua classe não é gerada. (Algum tempo quando colamos o arquivo de layout, então acontece). Em seguida, reconstruir projeto de Build> Rebuild( não construir ou criar projeto ). Ele irá gerar sua classe de vinculação de dados. ( Rebuild faz mágica para mim. )

8. Tenha o Android Studio mais recente

Depois de atualizar o AS para o Android Studio 3.2 , senti muitos bugs serem corrigidos na geração automática de vinculação de dados. Portanto, você também deve ter o AS mais recente.

Solução para <variables

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

Normalmente, quando colocamos uma variável no layout, ele cria um getter e um setter dela. E podemos usar binding.setItem(item);e binding.getItem();, mas se você não conseguir ver esses métodos, leia as informações abaixo.

1. Feche e abra o projeto do recente

Se você criou uma variável de dados - <variableem seu layout e ela não mostra seu setter e getter na classe de vinculação de dados, feche e abra do recente seu projeto.

2. Limpe o projeto após mudar o tipo

Se você alterou o tipo de algum <variableem seu layout e o tipo de setter getter não muda, então Clean project ( Build> Clean Project)

Palavras finais

Finalmente, se ainda assim sua classe de ligação não for gerada, temos nossa arma mais poderosa. - Reinicie o Android Studio: D

  • Primeiro, tente apenas reiniciar , isso sempre gera variáveis ​​do meu layout de ligação após reiniciar.
  • Se não funcionar, invalide o cache e reinicie .

Isso é tudo que eu faço para resolver meus erros de vinculação de dados. Se você tiver mais problemas, pode comentar aqui.

Khemraj
fonte
2
Se o problema continuar ... (8) Invalide e reinicie .... se não for resolvido, (9) altere dataBinding {enabled = false} ... build, e então dataBinding {enabled = true} build novamente ....
PravyNandas
1
No meu caso, tive que importar o classpath manualmente por algum motivo, o IDE não mostra isso como uma solução. Tnx :)
Ivan Kaloyanov
2
Salvou meu dia. Estava faltando o envoltório <layout> em meu arquivo de layout. Obrigado!
Juliano
Você também pode adicionar que o "import android.R" deve ser removido, se fizer parte da lista de importação. Isso resolveu meu problema com a referência não resolvida ao arquivo xml da atividade
Tim John
23

Classe DataBinding gerada automaticamente.

se o seu nome xml for activity_test, a classe Binding será ActivityTestBinding.

mas,

dataBinding {
        enabled = true
    }

layout deve ter layout como raiz

<layout xmlns:android="http://schemas.android.com/apk/res/android">
</layout>
ViramP
fonte
Estou procurando soultion por horas, faço muita magia gradle, mas eu uso ConstraintLayoutcomo uma raiz. Obrigado!
Alexey Markov
14

Eu tive o mesmo problema. Depois de ler os documentos SDK do Android, há apenas o nome do arquivo esperado a ser criado, mas nada sobre o que fazer se isso não acontecer. Percebi depois de mais algumas pesquisas que depois de remover o namespace para o elemento de layout como abaixo (usando seu exemplo), funcionou para mim.

    <?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> 
Ngaspama
fonte
10

No meu caso, a classe Binding foi gerada e instalada (mas pensei que não) ... mas não adiciona automaticamente a importação da referida classe à seção de importação de atividade / fragmento ... então ... OPÇÃO + ENTRAR :)

Krzysztof Kubicki
fonte
2
Bingo funcionou para mim, embora eu tivesse que digitar a importação manualmente, o intellisense não estava oferecendo a opção por qualquer motivo.
Rob
8

Depois de configurá-lo corretamente (incluindo o namespace xml e envolver tudo <layout>), o que funcionou para mim foi fazer Build -> Make project. Nem o Clean Project ou o Rebuild Project fizeram. Estou no Android Studio 2.3.1, usando as ferramentas de compilação 26.0.2. Não há necessidade de <data>tags.

Xtreme Biker
fonte
Essa deve ser marcada como a resposta correta. Resto, todos são apenas soluções alternativas. Não há necessidade de mover namespaces ou mesmo adicionar elemento de dados
Vicky Kapadia
8

se você faz o trabalho básico, para habilitar databainding em seu projeto, como use enable no gradle e use tag de layout em xml , quando você altera o código xml e não gera uma nova classe de databinding para aqueles xml, você pode usar uma maneira rápida para gerar apenas dados binding class in gradle-> other-> databindinggenbaseclassesDebug it fast more than bulid project inteiro. é gerar apenas classe de ligação de dados. insira a descrição da imagem aqui

Mahdi Azadbar
fonte
4
dataBinding {
        enabled = true
    }

Para ativar o novo compilador de vinculação de dados, adicione a seguinte opção ao seu arquivo gradle.properties:

android.databinding.enableV2=true
Samir Mangroliya
fonte
3

As classes de vinculação de dados são geradas durante a construção, portanto, depois de habilitar a vinculação de dados na construção do Gradle do aplicativo e envolver seu xml com a tag de layout, você deve reconstruir seu aplicativo. Se isso não ajudar, exclua sua pasta de construção e faça novamente.

Schadenfreude
fonte
2

Graças a esta resposta aqui - parece que o "namespace de layout" precisa ser eliminado ou você precisa de um novo nome exclusivo.

Aqui estão as opções que funcionaram para mim:

  1. Crie um novo nome para o layout para garantir que ele possa ser gerado. Isso resolveu meu problema, onde eu tinha um layout que foi criado primeiro, sem vinculação de dados - vamos chamá-lo fragment_abc.xml. Quando tentei adicionar vinculação de dados a ele, não foi reconhecido - mesmo após várias chamadas de cache e reinicialização de limpeza. No entanto, assim que fiz uma cópia do layout fragment_abc2.xml, obtive imediatamente o objeto .java / .class de vinculação de dados gerado.

  2. Depois de ver o trabalho acima, tentei apenas remover a pasta / build do módulo e reconstruir o projeto - isso funcionou para obter a vinculação de dados para o layout original.

Gene Bo
fonte
1

A única coisa que posso imaginar, se possível, é se você não tiver

dataBinding {
    enabled true
}

em seu arquivo Gradle. Caso contrário, basta adicioná-lo ao arquivo gradle. ie

android {
  ......

  dataBinding {
    enabled true
  }
}

em seguida, sincronize seu projeto. Se ainda falhar, pode ser necessário fazer Invalidate / Restart do seu Android Studio

Hassan Semiu Ayomon
fonte
Eu mencionei claramente em minha pergunta que após adicionar <variable>em xml ele está gerando classe Binding, então não há caso de não adicionar dataBindingno arquivo gradle, se eu não tiver adicionado, não deve gerar classe de ligação.
Ravi de
Antes de sincronizar e reiniciar. Por favor, tente 'fazer'. Vai treinar.
Nizamudeen Sherif
1

Eu não sei se vai funcionar para você ou não. Basta renomear o nome do arquivo XML do layout. Suponha que o nome do layout seja activity_main.xml, apenas altere-o para qualquer coisa como main.xml e renomeie-o para activity_main.xml . Então, você pode ver a opção de importação em ActivityMainBinding .

Espero que funcione para você.

Sudhansu
fonte
1

Ao trabalhar com um aplicativo Android multimodule, verifique o caminho da classe de ligação. Talvez você deva usar:

import com.yourcompany.app.android.modulename.databinding.FragmentABCtBinding em vez de:

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

kosiara - Bartosz Kosarzycki
fonte
1

Exclua layouts e desfaça, e certifique-se de que as classes de ligação geradas sejam importadas corretamente depois disso.

Ahmed AlAskalany
fonte
0

Eu tive o mesmo problema. Tudo que você fez correto. A coisa é que você precisa adicionar a variável dentro da tag de dados em xml. Para isso, você deve criar uma classe de modelo de amostra e adicioná-la como variável na tag de dados.

Até que você não verá ActivityMainBinding gerado.

Srinivasan
fonte
0

Tive um problema semelhante em que envolvi o layout e a vinculação de dados ativada no arquivo gradle. A atividade principal ainda não conseguia intelectualizar ou ver minhas aulas. O que consertou para mim foi adicionar a variável de ligação e importar a ligação de qualquer maneira. A partir daí, acabei de construir a solução e então parecia saber qual era a classe. De lá, pude importar minhas classes de caixa de camelo que foram geradas.

Stegnerd
fonte
0

Eu entendi o problema e o problema estava no layout, o campo usado não era uma String, era uma Data.

Parece que todo campo tem que ser texto para funcionar, pelo menos com o componente TexView.

Se você construir com o comando ./gradlew build --stacktrace

Isso mostra melhor os erros.

jativo
fonte
0

No meu caso, pensei que a classe gerada deveria aparecer com minhas classes usuais na srcpasta. Além disso, achei que o nome da classe gerada deveria ser um pouco diferente. Foi tudo erro meu. A classe gerada pode ser encontrada em buildpasta, build -> generated -> ...caminho. Se não houver importação da classe gerada em sua atividade, adicione a importação

import com.yourcompany.app.databinding.ActivityMainBinding;"
Kseniya
fonte
0

Caso você obtenha o seguinte erro em DataBindingUtil.setContentView

Referência não resolvida: activity_main

tudo que você precisa fazer é remover a seguinte instrução de importação

import android.R

Encontrei a solução em outro fórum. Fonte

Tim John
fonte
0

Se recentemente algum projeto existente migrou para o androidx , você precisa substituir sua importação de

import com.yourpackagename.BR;

para

import androidx.databinding.library.baseAdapters.BR;

Depois de 2 dias do Google finalmente consegui solução, qual funcionou para mim.

Milan Sheth
fonte
1
Não. Recurso de vinculação ( .BR. ) Como Recurso ( .R. ). É gerado com base nos recursos do seu projeto (id, drawable, color, ...) para que seja colocado dentro do pacote do seu projeto ( your.project.package.BR). Não dentro de uma biblioteca de terceiros, como androidx.databinding.library.baseAdapters.BR.
dphans
0

Há casos em que você não verá um arquivo no diretório gerado, você pode estar vinculando uma propriedade que não está declarada no viewmodel. Essencialmente, não dá um erro de lint se você fizer isso em xml.

Uzair
fonte
0

Se você está implementando o Serializable -> você deve implementar o Serializable

caso contrário, você obterá este erro. Espero que ajude alguém no futuro

No meu caso, uso a biblioteca Parcel. Perdi anotar @Parcel na minha subclasse

Ranjith Kumar
fonte
0

Além das etapas acima, você também pode verificar o tipo de variável. Certifique-se de que é String para TextView ou o mesmo definido no BindingAdapter. Por exemplo:

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

e em XML:

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

Isso causará o erro acima. Para corrigir, você pode criar a variável de idade do tipo String ou importar String em seu XML e usar da String.valueOf(age)seguinte maneira:

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

E em seu TextView:

android:text="@{String.valueOf(dataobject.age)}"
tímido
fonte
0

Minha solução foi usar como sufixo FragmentBinding no nome da classe.

Uma classe de ligação é gerada para cada arquivo de layout. Por padrão, o nome da classe é baseado no nome do arquivo de layout, convertendo-o para o caso Pascal e adicionando o sufixo Binding a ele. O nome do arquivo de layout acima é activity_main.xml, portanto, a classe gerada correspondente é ActivityMainBinding. Esta classe contém todas as ligações das propriedades de layout (por exemplo, a variável de usuário) para as visualizações do layout e sabe como atribuir valores para as expressões de ligação.

A nomenclatura do nome da atividade ou classe de fragmento pode variar em termos de prefixos. Porque o sufixo é sempre Vinculativo.

Depois de seguir a resposta de Khemraj e Invalidate Caches / Restart , você deve reescrever ActivityBinding ou FragmentBinding para obter as sugestões do IDE das classes que já foram geradas e NÃO codificar a importação.

No meu caso, estava tentando importar o nome da classe de trás para frente em FragmentCompetitionsBindingvez de CompetitionsFragmentBinding.

GL

Fonte

Braian Coronel
fonte
0

No meu caso, as classes de vinculação de dados não foram geradas porque eu excluí o mipmap Android Resource Directory. Recriei o diretório res / mipmap / e as classes de ligação de dados foram restabelecidas.

com erros
fonte
0

Eu encontrei um problema semelhante em que DataBinding falhou ao gerar a classe BindingImpl . No meu caso, foi um problema de um método na classe de dados onde o nome foi usado incorretamente: O modelo continha um método onSignInCliked () e no layout eu usei onSigninCliked () . Observe o SignIn vs Signin .

A mensagem de erro não foi suficiente e eu descobri o problema apenas quando usei o script de construção com a opção de rastreamento de pilha.

Ionut Negru
fonte
0

Certifique-se de que a vinculação de dados esteja ativada

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

Sincronizar projeto com o gradle dan clique no botão (Sincronizar projeto com Gradle)

Fahrizal89
fonte
0

Se houver um problema com seu arquivo XML, a classe Databinding não será gerada. Uma solução rápida seria percorrer o arquivo XML e verificar se há erros de sintaxe (geralmente destacados em vermelho). Os erros podem vir na forma de referências inexistentes ou erradas, erros tipográficos, etc.

Basicamente, certifique-se de que não haja nenhuma linha sublinhada em vermelho em seu código XML. Quando terminar, reconstrua e sua classe Databinding terá sido gerada.

Taslim Oseni
fonte
-1

1. Adicione abaixo no app gradle

 dataBinding {
        enabled = true
    }

2. No layout xml, escreva abaixo do código

<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.
Rohan Lodhi
fonte
3
Por que dataBinding requer permissão de internet, em um caso geral?
M.Pomeroy
1
@ M.Pomeroy sim, não é necessário, não editou a resposta obrigado
Rohan Lodhi
-5

use o caminho da classe 'com.android.databinding: dataBinder: 1.0-rc0'

Sumanta Banerjee
fonte
para gradle 1.5.0 e superior, não é necessário usar este caminho de classe.
Ravi de