Pericolul de a folosi kotlin.syntetic for block in layout

Fotografie de Justin Chrn pe Unsplash

Acum, odată cu apariția lui Kotlin în dezvoltarea pentru Android, a apărut un instrument util pentru a lega vizualizările din xml-layout la clasă. Acesta este kotlinx.android.synthetic. Nu mai este nevoie să folosiți metoda findViewById(). Este suficient să scrieți valoarea id-ului, care este specificată în xml, și ați putea folosi vizualizarea în clasă. există multe articole despre acest lucru, ca de exemplu descrierea oficială. Dar pot exista probleme neevidente cu utilizarea tag-ului <include> în layout. Să creăm un mic exemplu și să încercăm să arătăm un astfel de caz.

Aplicația de test este lista cu două elemente, fiecare dintre ele conține un buton cu text. La început se vor crea layout-uri pentru elemente – item1.xml și item2.xml. Fundalul din spatele butonului are culori diferite pentru o vizibilitate mai utilă.

Să ne concentrăm pe faptul că butoanele din articole au același id „button”. Este un lucru important.

În continuare adăugați aceste elemente la main_layout cu ajutorul tag-ului <include>:

Acum să le folosim în clasă ca layout:

Executați aplicația pentru a obține următorul rezultat:

Identificarea problemei

Acum să realizăm o mică particularitate, și să schimbăm textul butoanelor în cod. Va exista un text nou „Text modificat primul element” pentru primul buton, și „Text modificat al doilea element” pentru al doilea. Pentru legarea butoanelor se va folosi kotlinx.synthetic cu alias:

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

Este evident că butonul1 este vizualizat din item1.xml, iar butonul2 din item2.xml. Urmează să schimbăm textul pe OnCreate:

Să rulăm aplicația și să vedem rezultatul:

Oops! Nu este ceea ce ne așteptam. Textul primului buton a fost schimbat cu textul care a fost scris pentru al doilea, iar textul celui de-al doilea buton nu s-a schimbat absolut deloc.

Explicarea problemei

Să încercăm să înțelegem care este motivul acestui rezultat. Acum vedeți cum funcționează sintetic sub capotă. Pentru aceasta decompilați clasa kotlin în Java (Show Kotlin Bytecode -> Decompile for AndroidStudio). Acum, MainActivity arată astfel:

Acum putem înțelege cum funcționează sinteticul. Activitatea are HashMap, care utilizează id-ul vizualizării ca cheie și obiectul vizualizării ca valoare. Acesta este completat prin inițializare leneșă. În cazul nostru, primul apel la butonul1 caută valoarea HashMap prin cheia id = R.id.button. Deoarece nu există încă o astfel de valoare, metoda adaugă o pereche la hartă, în care id este cheia și un obiect-buton din item1 este valoarea. Ca rezultat, textul pentru primul buton este aplicat cu succes.

Apelul către butonul2, care are, de asemenea, id = R.id.button, verifică valoarea hărții pentru această cheie, găsește primul nostru View (butonul din primul element) și îl completează cu valoarea pentru al doilea buton. Ca rezultat, primul buton schimbă textul de două ori, al doilea nu o dată

Soluția problemei

Pentru început, puteți folosi id-uri diferite pentru fiecare vizualizare. Dar, dacă nu este util, puteți reveni la findViewById:

Să rulăm aplicația și să vedem rezultatul:

Acum funcționează corect!

Concluzie

Noile caracteristici ale limbajului dau o lof ot util, dar trebuie să înțelegeți cum funcționează pentru a evita problemele.

Mulțumesc pentru că ați citit acest articol! Sper că vă va fi de folos

.

Lasă un comentariu