A tão esperada ligação de exibição no Android

Há alguns dias, o Google lançou o Android Studio 3.6 Canary 11, a principal inovação em que foi o View Binding, que foi descrito em maio no Google I / O 2019.



View Binding é uma ferramenta que facilita escrever código para interagir com a view. Quando você ativa a Visualização de Ligação em um módulo específico, ele gera classes de ligação para cada arquivo de layout no módulo. O objeto de classe de ligação gerado contém links para todas as visualizações do arquivo de marcação para o qual android:id está especificado.


Como habilitar


Para ativar a Ligação de exibição no módulo, você precisa adicionar um elemento ao arquivo build.gradle :


 android { ... viewBinding { enabled = true } } 

Você também pode especificar que não precisa gerar uma classe de ligação para um arquivo de marcação específico. Para fazer isso, você precisa especificar o atributo tools:viewBindingIgnore="true" na visualização raiz no arquivo de marcação desejado.


Como usar


Cada classe de ligação gerada contém um link para a visualização raiz da marcação ( root ) e links para todas as visualizações que possuem um ID. O nome da classe gerada é formado como "nome do arquivo de marcação" traduzido em caixa de camelo + "Vinculação".


Por exemplo, para o arquivo de marcação result_profile.xml :


 <LinearLayout ... > <TextView android:id="@+id/name" /> <ImageView android:cropToPadding="true" /> <Button android:id="@+id/button" android:background="@drawable/rounded_button" /> </LinearLayout> 

A classe ResultProfileBinding será gerada, contendo 2 campos: TextView name e Button button . Para o ImageView nada será gerado, pois não possui id . Também na classe ResultProfileBinding haverá um método getRoot() que retorna a raiz LinearLayout .


Para criar um objeto da classe ResultProfileBinding , você precisa chamar o método estático inflate() . Depois disso, você pode usar a visualização raiz como a content view na Activity :


 private lateinit var binding: ResultProfileBinding @Override fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) binding = ResultProfileBinding.inflate(layoutInflater) setContentView(binding.root) } 

binding posteriores podem ser usadas para obter a visualização:


 binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() } 

Diferenças de outras abordagens


As principais vantagens do View Binding são a segurança nula e a segurança de tipo.


Ao mesmo tempo, se alguma visualização estiver disponível em um layout, mas não em outro ( layout-land , por exemplo), um campo @Nullable será gerado para ele na classe de ligação.


Além disso, se em diferentes configurações de marcação houver uma visualização com o mesmo ID, mas com tipos diferentes, um campo com o tipo android.view.View será gerado para eles.
(Pelo menos na versão 3.6 do Canary 11)


Em geral, seria conveniente se o campo gerado tivesse o tipo específico mais possível. Por exemplo, para um Button em uma configuração e um TextView em outra, TextView gerado um campo do tipo TextView ( public class Button extends TextView ).


Ao usar a Ligação de exibição, todas as inconsistências entre a marcação e o código serão detectadas no estágio de compilação, o que evitará erros desnecessários durante a operação do aplicativo.


Uso no RecyclerView.ViewHolder


Nada impede o uso de Vinculação de vista ao criar uma view para um RecyclerView.ViewHolder :


 class PersonViewHolder(private val itemPersonBinding: ItemPersonBinding) : RecyclerView.ViewHolder(itemPersonBinding.root) { fun bind(person: Person) { itemPersonBinding.name.text = person.name } } 

No entanto, para criar um ViewHolder precisará escrever um pequeno boilerplate:


 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PersonViewHolder { val layoutInflater = LayoutInflater.from(parent.context) val itemPersonBinding = ItemPersonBinding.inflate(layoutInflater, parent, false) return PersonViewHolder(itemPersonBinding) } 

Seria mais conveniente se, ao trabalhar com RecyclerView.ViewHolder o método inflate(...) não tivesse o parâmetro layoutInflater , mas o recebesse do parent transmitido.


Aqui também é necessário mencionar que, ao usar a Vinculação de vista, a view pesquisada por findViewById() apenas uma vez quando o método inflate() é inflate() . Isso oferece uma vantagem sobre kotlin-android-extensions , em que o cache de view por padrão funcionava apenas em Activity and Fragment , e o RecyclerView.ViewHolder exigia configuração adicional .


Em geral, o View Binding é uma coisa muito conveniente e fácil de começar a usar em projetos existentes. A Creator Butter Knife já recomenda mudar para a opção Exibir encadernação.


É uma pena que esse instrumento não tenha aparecido há vários anos.

Source: https://habr.com/ru/post/pt467295/


All Articles