A kotlin használatának veszélye.syntetic for block in layout

Photo by Justin Chrn on Unsplash

Most, a Kotlin megjelenésével az Android fejlesztésében megjelent egy hasznos eszköz az xml-layout nézetek osztályhoz kötésére. Ez a kotlinx.android.synthetic. Nem kell többé a findViewById() metódust használni. Elég kiírni az xml-ben megadott id értékét, és máris használhatod a view-t az osztályban. erről sok cikk szól, mint például a hivatalos leírás. De lehetnek nem nyilvánvaló problémák a <include> tag használatával az elrendezésben. Hozzunk létre egy kis példát, és próbáljuk meg bemutatni egy ilyen esetet.

A tesztalkalmazás a lista két elemmel, mindegyik tartalmaz gombot szöveggel. Először létrehozza az elemek elrendezését – item1.xml és item2.xml. A háttér a gomb mögött különböző színű a hasznosabb láthatóság érdekében.

Fókuszáljunk arra, hogy az elemek gombjai azonos “button” id-vel rendelkeznek. Ez egy fontos dolog.

Következőleg adjuk hozzá ezeket az elemeket a main_layouthoz a <include> tag segítségével:

Most használjuk fel az osztályban layoutként:

Futtassuk az alkalmazást, hogy a következő eredményt kapjuk:

A probléma azonosítása

Most csináljunk egy kis funkciót, és változtassuk meg a gombok szövegét a kódban. Az első gombhoz új szöveg lesz “Megváltozott szöveg első elem”, a másodikhoz pedig “Megváltozott szöveg második elem”. A gombokhoz való kötődéshez kotlinx.synthetic-et fogunk használni alias:

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

Ez nyilvánvalóan a button1 az item1.xml, a button2 az item2.xml fájlból való nézet. Ezután változtassuk meg a szöveget az OnCreate-on:

Futtassuk az alkalmazást és nézzük meg az eredményt:

Oops! Nem erre számítottunk. Az első gomb szövege a második gombra írt szövegre változott, a második gomb szövege pedig egyáltalán nem változott.

A probléma magyarázata

Próbáljuk megérteni, mi az oka ennek az eredménynek. Most nézzük meg, hogyan működik a motorháztető alatt a szintetikus munka. Ehhez dekompiláljuk a kotlin osztályt Java-ra (Show Kotlin Bytecode -> Decompile for AndroidStudio). Most MainActivity így néz ki:

Most már értjük, hogyan működik a szintetikus. Az aktivitásnak van HashMap-ja, amely a nézet id-jét használja kulcsként, és a nézet-objektumot értékként. Ezt lusta inicializálással töltjük fel. Esetünkben a button1 első hívása a HashMap értékét az id = R.id.button kulcs alapján keresi. Mivel ilyen érték még nincs, a módszer hozzáad egy párt a térképhez, ahol kulcsként az id, értékként pedig egy gomb-objektum az item1-ből. Ennek eredményeképpen az első gomb szövege sikeresen alkalmazásra kerül.

A button2 hívása, amelynek szintén id = R.id.button, ellenőrzi a map értékét erre a kulcsra, megtalálja az első View-unkat (az első itemből származó gombot), és kitölti azt a második gomb értékével. Ennek eredményeképpen az első gomb kétszer változtatja meg a szöveget, a második nem egyszer

A probléma megoldása

Az egyes nézetekhez különböző id-t használhatunk. De ha ez nem hasznos, akkor visszatérhetünk a findViewById-re:

Futtassuk az alkalmazást, és nézzük meg az eredményt:

Most már helyesen működik!

Következtetés

A nyelv új funkciói sok hasznosat adnak, de a problémák elkerülése érdekében meg kell értened, hogyan működik.

Köszönjük, hogy elolvastad ezt a cikket! Remélem, hasznos lesz számodra

Szólj hozzá!