A biblioteca Data Binding gera classes de vinculação que podem ser usadas para acessar as variáveis e visualizações do layout. Esta documentação mostra como criar e personalizar as classes de vinculação geradas.
A classe de vinculação gerada vincula as variáveis de layout às visualizações dentro do
layout. Você pode personalizar o nome e o pacote da
vinculação. Todas as classes de vinculação geradas são herdadas da
classe ViewDataBinding
.
Uma classe de vinculação é gerada para cada arquivo de layout. Por padrão, o nome da
classe é o nome do arquivo de layout convertido para o padrão Pascal com o sufixo Binding
adicionado a ela. Por exemplo, se o nome do arquivo do layout for
activity_main.xml
, a classe gerada correspondente será ActivityMainBinding
.
Essa classe contém todas as vinculações das propriedades de layout para as visualizações
e sabe como atribuir valores às expressões de vinculação.
Criar um objeto de vinculação
O objeto de vinculação é criado imediatamente após a inflação do layout para garantir
que a hierarquia de visualização não seja modificada antes de se vincular às visualizações com
expressões no layout. O método mais comum para vincular o objeto a um
layout é usar os métodos estáticos na classe de vinculação. Você pode inflar a
hierarquia de visualização e vincular o objeto a ela usando o método inflate()
da
classe de vinculação, conforme mostrado no exemplo abaixo:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.root); }
Há uma versão alternativa do método inflate()
que usa um objeto
ViewGroup
, além do objeto
LayoutInflater
, conforme
mostrado no exemplo a seguir.
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)
Java
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
Se o layout for inflado usando um mecanismo diferente, você poderá vinculá-lo separadamente, da seguinte maneira:
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)
Java
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
Às vezes, você não sabe o tipo de vinculação com antecedência. Nesses casos, você pode
criar a vinculação usando a classe
DataBindingUtil
,
conforme demonstrado no snippet de código a seguir.
Kotlin
val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent) val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)
Java
View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent); ViewDataBinding binding = DataBindingUtil.bind(viewRoot);
Se você estiver usando itens de vinculação de dados dentro de um adaptador
Fragment
,
ListView
ou
RecyclerView
,
talvez prefira usar os métodos
inflate()
das classes de vinculação ou a
classe DataBindingUtil
, conforme
mostrado no exemplo de código a seguir.
Kotlin
val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false) // or val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
Java
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); // or ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
Visualizações com códigos
A biblioteca Data Binding cria um campo imutável na classe de vinculação para
cada visualização que tem um ID no layout. Por exemplo, a biblioteca Data Binding
cria os campos firstName
e lastName
do tipo TextView
no
seguinte layout:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:id="@+id/firstName"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"
android:id="@+id/lastName"/>
</LinearLayout>
</layout>
A biblioteca extrai as visualizações, incluindo os IDs, da hierarquia de visualizações em uma
única passagem. Esse mecanismo pode ser mais rápido do que chamar o método
findViewById()
para todas as visualizações no layout.
Os IDs não são tão necessários quanto são sem a vinculação de dados, mas ainda há alguns casos em que o acesso a visualizações é necessário no código.
Variáveis
A biblioteca Data Binding gera métodos do acessador para cada variável declarada
no layout. Por exemplo, o layout a seguir gera os métodos setter e getter
na classe de vinculação para as variáveis user
, image
e note
:
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
ViewStubs
Ao contrário das visualizações normais, os objetos ViewStub
começam como visualizações invisíveis. Quando ficam visíveis ou são explicitamente inflados,
eles se substituem no layout inflando outro layout.
Como a ViewStub
desaparece da hierarquia de visualização, a visualização no
objeto de vinculação também precisa desaparecer para que ela seja reivindicada pela coleta de lixo.
Como as visualizações são finais, um objeto
ViewStubProxy
substitui a ViewStub
na classe de vinculação gerada, oferecendo
acesso à ViewStub
quando ela existe e à hierarquia de visualização inflada
quando a ViewStub
é inflada.
Ao inflar outro layout, uma vinculação precisa ser estabelecida para o novo layout.
Portanto, o ViewStubProxy
precisa detectar o ViewStub
OnInflateListener
e estabelecer a vinculação quando necessário. Como apenas um listener pode existir por
vez, o ViewStubProxy
permite definir um OnInflateListener
, que é chamado
depois que a vinculação é estabelecida.
Vinculação imediata
Quando uma variável ou um objeto observável muda, a vinculação é programada para mudar
antes do próximo frame. No entanto, há momentos em que a vinculação precisa ser executada
imediatamente. Para forçar a execução, use o
método
executePendingBindings()
.
Variáveis dinâmicas
Às vezes, a classe de vinculação específica é desconhecida. Por exemplo, um
RecyclerView.Adapter
que opera em layouts arbitrários não conhece a classe de vinculação específica. Ele
precisa atribuir o valor de vinculação durante a chamada para o
método
onBindViewHolder()
.
No exemplo abaixo, todos os layouts a que o RecyclerView
se vincula têm uma
variável item
. O objeto BindingHolder
tem um método getBinding()
que retorna a
classe base
ViewDataBinding
.
Kotlin
override fun onBindViewHolder(holder: BindingHolder, position: Int) { item: T = items.get(position) holder.binding.setVariable(BR.item, item); holder.binding.executePendingBindings(); }
Java
public void onBindViewHolder(BindingHolder holder, int position) { final T item = items.get(position); holder.getBinding().setVariable(BR.item, item); holder.getBinding().executePendingBindings(); }
Linha de execução em segundo plano
Você pode mudar seu modelo de dados em uma linha de execução em segundo plano, desde que ele não seja uma coleção. A vinculação de dados localiza cada variável ou campo durante a avaliação para evitar problemas de simultaneidade.
Nomes de classes de vinculação personalizados
Por padrão, uma classe de vinculação é gerada com base no nome do arquivo de layout,
começando com uma letra maiúscula, removendo sublinhados ( _), colocando em maiúscula a
letra seguinte e colocando a palavra Binding como sufixo. Por exemplo, o arquivo de layout
contact_item.xml
gera a classe ContactItemBinding
. A classe é colocada
em um pacote databinding
no pacote do módulo. Por exemplo, se o pacote
do módulo for com.example.my.app
, a classe de vinculação será colocada no
pacote com.example.my.app.databinding
.
As classes de vinculação podem ser renomeadas ou colocadas em pacotes diferentes ajustando o
atributo class
do elemento data
. Por exemplo, o layout a seguir
gera a classe de vinculação ContactItem
no pacote databinding
do
módulo atual:
<data class="ContactItem">
...
</data>
Você pode gerar a classe de vinculação em um pacote diferente, adicionando um ponto como prefixo ao nome da classe. O exemplo abaixo gera a classe de vinculação no pacote do módulo:
<data class=".ContactItem">
...
</data>
Também é possível usar o nome completo do pacote em que você quer que a classe de vinculação seja
gerada. O exemplo a seguir cria a classe de vinculação ContactItem
no
pacote com.example
:
<data class="com.example.ContactItem">
...
</data>
Outros recursos
Para saber mais sobre a vinculação de dados, consulte os recursos adicionais a seguir.
- Exemplos da biblioteca Android Data Binding (link em inglês)
- Vinculação de dados no Android
- Vinculação de dados: lições aprendidas
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Layouts e expressões de vinculação
- Biblioteca Data Binding
- Vinculação de visualizações