Vinculação de visualizações Parte do Android Jetpack.
A vinculação de visualizações é um recurso que facilita a criação de códigos que interajam com visualizações. Quando a vinculação de visualizações é ativada em um módulo, ela gera uma classe de vinculação para cada arquivo de layout XML presente nesse módulo. A instância de uma classe de vinculação contém referências diretas a todas as visualizações que têm um ID no layout correspondente.
Na maioria dos casos, a vinculação de visualizações substitui findViewById
.
Configurar
A vinculação de visualizações é ativada módulo por módulo. Para ativar a vinculação de visualizações em um
módulo, defina a opção de build viewBinding
como true
no arquivo
build.gradle
do módulo, conforme mostrado no exemplo abaixo.
Groovy
android { ... buildFeatures { viewBinding true } }
Kotlin
android { ... buildFeatures { viewBinding = true } }
Se você quiser que um arquivo de layout seja ignorado ao gerar classes de vinculação, adicione
o atributo tools:viewBindingIgnore="true"
à visualização raiz desse arquivo
de layout:
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
Uso
Se a vinculação de visualizações estiver ativada para um módulo, uma classe de vinculação será gerada para cada arquivo de layout XML que o módulo contiver. Cada classe de vinculação contém referências à visualização raiz e a todas as visualizações que têm um ID. O nome da classe de vinculação é gerado pela conversão do nome do arquivo XML no padrão PascalCase e da adição da palavra "Binding" ao final.
Por exemplo, considere um arquivo de layout chamado result_profile.xml
que contém
o seguinte:
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
A classe de vinculação gerada terá o nome ResultProfileBinding
. Essa classe tem dois
campos: um TextView
com o nome name
e um Button
com o nome button
. A
ImageView
no layout não tem ID. Portanto, não há referência a ela na
classe de vinculação.
Cada classe de vinculação também inclui um método getRoot()
, fornecendo uma referência
direta para a visualização raiz do arquivo de layout correspondente. Neste exemplo,
o método getRoot()
na classe ResultProfileBinding
retorna a
visualização raiz LinearLayout
.
As seções abaixo demonstram o uso de classes de vinculação geradas em atividades e fragmentos.
Usar a vinculação de visualizações em atividades
Para configurar uma instância da classe de vinculação para uso com uma atividade, siga as
etapas abaixo no método
onCreate()
da atividade:
- Chame o método estático
inflate()
incluído na classe de vinculação gerada. Isso cria uma instância da classe de vinculação para a atividade usar. - Receba uma referência à visualização raiz chamando o método
getRoot()
ou usando a sintaxe da propriedade Kotlin. - Transmita a visualização raiz para
setContentView()
para torná-la a visualização ativa na tela.
Essas etapas são mostradas no exemplo a seguir:
Kotlin
private lateinit var binding: ResultProfileBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ResultProfileBinding.inflate(layoutInflater) val view = binding.root setContentView(view) }
Java
private ResultProfileBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ResultProfileBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); }
Agora, você pode usar a instância da classe de vinculação para referenciar qualquer uma das visualizações:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
Java
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
Usar a vinculação de visualizações em fragmentos
Para configurar uma instância da classe de vinculação para uso com um fragmento, siga
estas etapas no método
onCreateView()
do fragmento:
- Chame o método estático
inflate()
incluído na classe de vinculação gerada. Isso cria uma instância da classe de vinculação para o uso do fragmento. - Receba uma referência à visualização raiz chamando o método
getRoot()
ou usando a sintaxe da propriedade Kotlin. - Retorne a visualização raiz do método
onCreateView()
para torná-la a visualização ativa na tela.
Kotlin
private var _binding: ResultProfileBinding? = null // This property is only valid between onCreateView and // onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { _binding = ResultProfileBinding.inflate(inflater, container, false) val view = binding.root return view } override fun onDestroyView() { super.onDestroyView() _binding = null }
Java
private ResultProfileBinding binding; @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = ResultProfileBinding.inflate(inflater, container, false); View view = binding.getRoot(); return view; } @Override public void onDestroyView() { super.onDestroyView(); binding = null; }
Agora, você pode usar a instância da classe de vinculação para referenciar qualquer uma das visualizações:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
Java
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
Dar dicas para diferentes configurações
Quando você declara visualizações em várias configurações, às vezes faz sentido usar um tipo de visualização diferente, dependendo do layout específico. O snippet de código abaixo mostra um exemplo disso:
# in res/layout/example.xml
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" />
Nesse caso, você pode esperar que a classe gerada exponha um campo userBio
do tipo TextView
, porque TextView
é a classe base comum. Devido a
limitações técnicas, o gerador de código de vinculação de visualizações não pode determinar isso e
gera um campo View
. Isso exige a transmissão do campo mais tarde com
binding.userBio as TextView
.
Para contornar essa limitação, a vinculação de visualizações oferece suporte a um atributo
tools:viewBindingType
, permitindo que você informe ao compilador qual tipo usar no código gerado.
No exemplo anterior, é possível usar esse atributo para fazer o compilador
gerar o campo como um TextView
:
# in res/layout/example.xml (unchanged)
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />
Em outro exemplo, suponha que você tenha dois layouts, um que contém um
BottomNavigationView
e outro que contém um NavigationRailView
. As duas
classes estendem NavigationBarView
, que contém a maioria dos detalhes de
implementação. Caso seu código não precise saber exatamente qual subclasse está presente
no layout atual, você pode usar tools:viewBindingType
para definir o tipo
gerado como NavigationBarView
nos dois layouts:
# in res/layout/navigation_example.xml
<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
# in res/layout-w720/navigation_example.xml
<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
A vinculação de visualizações não pode validar o valor deste atributo ao gerar o código. Para evitar erros de tempo de compilação e execução, o valor precisa atender às seguintes condições:
- O valor precisa ser uma classe herdada de
android.view.View
. O valor precisa ser uma superclasse da tag em que é colocado. Por exemplo, os seguintes valores não funcionam:
<TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. --> <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->
O tipo final precisa ser resolvido de forma consistente em todas as configurações.
Diferenças de findViewById
A vinculação de visualizações tem vantagens importantes em relação ao uso de findViewById
:
- Segurança do tipo nulo:como a vinculação de visualizações cria referências diretas a visualizações,
não há risco de uma exceção de ponteiro nulo devido a um ID de visualização inválido.
Além disso, quando uma visualização está presente apenas em algumas configurações de um
layout, o campo que contém a referência na classe de vinculação é marcado
com
@Nullable
. - Segurança de tipo:os campos em cada classe de vinculação têm tipos correspondentes às visualizações referenciadas no arquivo XML. Isso significa que não há risco de uma exceção de transmissão de classe.
Essas diferenças significam incompatibilidades entre seu layout e seu código resultando em falha no build durante a compilação, e não no momento da execução.
Comparação com a vinculação de dados
A vinculação de visualizações e a vinculação de dados geram classes que podem ser usadas para referenciar visualizações diretamente. No entanto, a vinculação de visualizações se destina a casos de uso mais simples e oferece os seguintes benefícios em relação à vinculação de dados:
- Compilação mais rápida:a vinculação de visualizações não exige processamento de anotações, então os tempos de compilação são mais rápidos.
- Facilidade de uso:a vinculação de visualizações não exige arquivos de layout XML especialmente marcados, por isso é mais rápido para adotá-los nos seus apps. Depois que você ativa a vinculação de visualizações em um módulo, ela é aplicada automaticamente a todos os layouts desse módulo.
Por outro lado, a vinculação de visualizações tem as seguintes limitações em comparação com a vinculação de dados:
- A vinculação de visualizações não oferece suporte a variáveis ou expressões de layout, então não pode ser usada para declarar conteúdo dinâmico da interface diretamente de arquivos de layout XML.
- A vinculação de visualizações não tem suporte à vinculação de dados bidirecional.
Devido a essas considerações, em alguns casos é melhor usar a vinculação de visualizações e de dados em um projeto. Você pode usar a vinculação de dados em layouts que exigem recursos avançados e usar a vinculação de visualizações em layouts que não exigem.
Outros recursos
Para saber mais sobre a vinculação de visualizações, consulte os recursos abaixo:
Exemplos
Blogs
Vídeos
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Migrar de sintéticos do Kotlin para vinculação de visualizações do Jetpack
- Layouts e expressões de vinculação
- Arquitetura do app: camada de interface — guia para Desenvolvedores Android