Het gevaar van het gebruik van kotlin.syntetic voor blok in lay-out

Foto door Justin Chrn op Unsplash

Nu, met de komst van Kotlin in de ontwikkeling voor Android, is er een handig hulpmiddel verschenen om weergaven van xml-lay-out aan klasse te binden. Dit is kotlinx.android.synthetic. Er is geen noodzaak om de methode findViewById() meer te gebruiken. Er is genoeg om de waarde van id, die in xml is opgegeven, te schrijven en je zou view in class kunnen gebruiken. Er zijn veel artikelen over, zoals de officiële beschrijving bijvoorbeeld. Maar er kunnen niet voor de hand liggende problemen zijn met het gebruik van tag <include> in layout. Laten we een klein voorbeeld maken en proberen zo’n geval te laten zien.

Test app is de lijst met twee items, die elk een knop met tekst bevatten. Op het eerste zal maken lay-outs voor items – item1.xml en item2.xml. De achtergrond achter de knop heeft verschillende kleuren voor meer nuttige zichtbaarheid.

Laten we ons richten op dat de knoppen in de items hebben dezelfde id “knop”. Het is belangrijk ding.

Volgende toevoegen die items aan main_layout met hulp <include> tag:

Nu laten we het gebruiken in klasse als lay-out:

Run de toepassing om het volgende resultaat te krijgen:

Identificatie van het probleem

Nu laten we een kleine functie maken, en de tekst van de knoppen in de code veranderen. Er komt een nieuwe tekst “Gewijzigde tekst eerste item” voor de eerste knop, en “Gewijzigde tekst tweede item” voor de tweede. Voor het binden aan knoppen wordt gebruik gemaakt van kotlinx.synthetic met alias:

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

Het is duidelijk dat knop1 een view is van item1.xml, en knop2 van item2.xml. Verander vervolgens de tekst op OnCreate:

Laten we de app draaien en kijken naar het resultaat:

Oeps! Het is niet wat we verwachtten. De tekst van de eerste knop is veranderd in de tekst die was geschreven voor de tweede knop, en de tekst van de tweede knop is absoluut niet veranderd.

Uitleg van het probleem

Laten we eens proberen te begrijpen wat de reden is van dit resultaat. Nu zien hoe werk synthetisch onder kap. Voor het decompileren kotlin klasse naar Java (Toon Kotlin Bytecode -> Decompile voor AndroidStudio). Nu ziet MainActivity er als volgt uit:

Nu kunnen we begrijpen hoe de synthetische werkt. Activiteit heeft HashMap, die id van view gebruikt als sleutel, en view-object als waarde. Het wordt gevuld door luie initialisatie. In ons geval, de eerste oproep aan button1 zoekt naar de HashMap waarde met de sleutel id = R.id.button. Omdat die waarde er nog niet is, voegt de methode een paar toe aan de map, met id als sleutel, en een knop-object uit item1 als waarde. Als resultaat wordt de tekst voor de eerste knop met succes toegepast.

De aanroep naar button2, die ook id = R.id.button heeft, controleert de map waarde voor deze sleutel, vindt onze eerste View (de knop van het eerste item), en vult het met de waarde voor de tweede knop. Het resultaat is dat de eerste knop twee keer van tekst verandert, de tweede niet één keer

Oplossing van het probleem

Zoals eerst, kunt u verschillende id gebruiken voor elke view. Maar als het niet nuttig, kunt u terugkeren naar findViewById:

Laten we de app en zie het resultaat:

Nu werkt het correct!

Conclusie

Nieuwe functies van de taal geven een hoop nuttige, maar je moet begrijpen hoe het werkt om problemen te voorkomen.

Dank voor het lezen van dit artikel! Ik hoop dat het nuttig voor u zal zijn

Plaats een reactie