O perigo de usar o kotlin.syntetic for block in layout

>

>

Foto por Justin Chrn em Unsplash

Agora, com o advento do Kotlin no desenvolvimento para Android, uma ferramenta útil apareceu para vincular vistas de xml-layout para classe. Isto é kotlinx.android.sintético. Não há necessidade de usar o método findViewById() mais. Há o suficiente para escrever o valor do id, aquele especificado em xml, e você pode usar o view na classe. Há muitos artigos sobre isso, como descrição oficial, por exemplo. Mas pode haver problemas não óbvios com o uso da tag <include> no layout. Vamos criar um pequeno exemplo e tentar mostrar esse caso.

Test app é a lista com dois itens, cada um contém um botão com texto. A princípio vamos criar layouts para itens – item1.xml e item2.xml. O fundo do botão tem cores diferentes para uma visibilidade mais útil.

Foque o foco do botão nos itens que têm o mesmo “botão” de id. É uma coisa importante.

Próximo adicionar esses itens ao main_layout com ajuda <include> tag:

Agora vamos usá-lo na classe como layout:

Executar a aplicação para obter o seguinte resultado:

Identificação do problema

Agora vamos fazer um pequeno recurso, e mudar o texto dos botões em código. Haverá um novo texto “Texto Alterado Primeiro Item” para o primeiro botão, e “Texto Alterado Segundo Item” para o segundo. Para ligação a botões será usado kotlinx.synthetic com alias:

import kotlinx.android.synthetic.main.item1.button as button1
import kotlinx.android.synthetic.main.item2.button as button2

É óbvio que o botão1 é visto a partir do item1.xml, botão2 a partir do item2.xml. A seguir altere o texto em OnCreate:

>

Vamos executar a aplicação e ver o resultado:

>

>

>

>>

Oops! Não é o que esperávamos. O texto do primeiro botão foi alterado para o texto que foi escrito para o segundo, e o texto do segundo botão não foi absolutamente alterado.

Explicação do problema

Tentemos compreender qual é a razão deste resultado. Agora veja como funciona o sintético sob o capô. Para decompilar a classe kotlin para Java (Mostrar Kotlin Bytecode ->Descompilar para AndroidStudio). Agora a MainActivity parece com isto:

Agora podemos compreender como funciona o sintético. A actividade tem HashMap, que usa id de view como chave, e view-object como valor. É preenchido por inicialização preguiçosa. No nosso caso, a primeira chamada ao botão1 procura o valor HashMap pela tecla id = R.id.button. Como ainda não existe tal valor, o método adiciona um par ao mapa, onde id como chave, e um botão-objecto do item1 como valor. Como resultado, o texto para o primeiro botão é aplicado com sucesso.

A chamada para o botão2, que também tem id = R.id.button, verifica o valor do mapa para esta chave, encontra a nossa primeira Vista (o botão do primeiro item), e preenche-o com o valor para o segundo botão. Como resultado o primeiro botão muda de texto duas vezes, secone one no one time

Solução do problema

Como primeiro botão, pode usar id diferente para cada vista. Mas se não for útil, pode voltar a findViewById:

>

Deixar correr a aplicação e ver ao resultado:

>

>

Agora funciona correctamente!

Conclusão

Novas características da linguagem dão um lof ot útil, mas você deve entender como funciona para evitar problemas.

Bancos pela leitura deste artigo! Espero que seja útil para si

Deixe um comentário