1 of 38

Tehnici avansate pentru

dezvoltarea aplicațiilor mobile

3 - Compose - Starea

2 of 38

Starea și compoziția

2

3 of 38

Fazele Compose

  • 3 faze pentru afișarea UI-ului
    • Compoziția - descriere a UI-ului (arbore)
    • Layout - măsurare și plasare
    • Desenarea - randarea

3

4 of 38

Compoziția și recompoziția

  • UI declarativ = declarăm în cod cum ar trebui să arate UI-ul

  • Compoziție: descrierea UI-ului construit de Compose atunci când se execută composables

3 - Compose - Starea

4

5 of 38

Compoziția și recompoziția

  • Compoziție inițială: crearea unei Compoziții prin rularea composables pentru prima dată.

  • Recompoziție: rularea din nou a funcțiilor composables pentru a actualiza Compoziția atunci când datele se modifică

  • Compoziția este produsă doar la compoziția inițială sau la recompoziție

3 - Compose - Starea

5

6 of 38

Compoziția

Nodurile din arbore - informațiile pentru fazele următoare

6

7 of 38

Starea

  • Compose trebuie să urmărească starea

  • Starea este orice valoare care se poate schimba în timp

  • O modificare de stare cauzează o recompoziție

3 - Compose - Starea

7

8 of 38

Câmp text - fără actualizare

8

9 of 38

Câmp text - fără actualizare

  • Un câmp de text nu se va actualiza automat atunci când scriem în el
    • Se actualizează doar când value primește o nouă valoare

  • UI-ul nu se actualizează dacă nu se schimbă starea
    • Trebuie să reținem cumva starea => recompoziție

3 - Compose - Starea

9

10 of 38

Salvarea stării

Starea = un obiect memorat în Compoziție

10

11 of 38

by

  • Cuvantul cheie by
    • prescurtarea de la “provided by”

  • Folosit pentru delegarea proprietății
    • Delegă setarea și obținerea valorii

3 - Compose - Starea

11

12 of 38

remember

  • Pentru a stoca un obiect (stare) în Compoziție trebuie să folosim remember

  • Valoarea este stocată în timpul compoziției inițiale și este folosită în timpul recompoziției

3 - Compose - Starea

12

13 of 38

remember

  • remember poate să stocheze obiecte mutable sau immutable (read-only)

  • Funcția care a apelat remember este scoasă din Compoziție
    • => obiectul este scos din Compoziție

13

14 of 38

State și MutableState

  • State și MutableState sunt tipuri observabile integrate în runtime-ul Compose

  • Tipul State este immutable
  • Tipul MutableState este mutable

3 - Compose - Starea

14

15 of 38

mutableStateOf

  • Funcția mutableStateOf() creează un obiect MutableState
    • reține starea, este mutable și observabil

  • Orice modificare a lui value declanșază o recompoziție a tuturor funcțiilor Composable care citesc value

3 - Compose - Starea

15

16 of 38

Funcționare remember

  • La prima rulare:
    • remember execută lambda
    • salvează valoarea în Compoziție
  • La rulările ulterioare
    • returnează valoarea stocată deja în Compoziție

16

17 of 38

mutableStateOf

  • Moduri echivalente de a declara un obiect MutableState într-un Composable:

3 - Compose - Starea

17

18 of 38

Salvarea stării - exemplu

3 - Compose - Starea

18

19 of 38

Salvarea stării - exemplu

  • Variabila name este salvată în Composable:
    • var name by remember { mutableStateOf("") }

  • Valoarea inițială este un String gol

  • Atunci când utilizatorul introduce un text se apelează callback-ul lambda onValueChange
    • Atunci valoarea este actualizată cu textul introdus

3 - Compose - Starea

19

20 of 38

Salvarea stării - exemplu

  • name este un obiect observabil
    • => modificarea lui va declanșa o recompoziție

  • Noua valoare a lui name ramane stocată și în timpul recompoziției

  • Valoarea poate fi folosită ca parametru pentru alți copii Composable (Text și OutlinedTextField)

  • Valoarea poate fi folosită în logica Composable-ului (if)

3 - Compose - Starea

20

21 of 38

Salvarea stării

  • remember
    • reține starea în cazul recompozițiilor
    • nu reține starea în cazul modificărilor de configurație

  • rememberSaveable
    • reține starea în cazul modificărilor de configurație
    • valorile stocate într-un Bundle

21

22 of 38

Transferul stării

22

23 of 38

Stateless & stateful

  • Un composable este stateless dacă nu are o stare
    • Nu este stocat niciun obiect observabil
    • Afișează doar ce primește ca argumente

  • Un composable este stateful dacă are o stare
    • Este stocat cel puțin un obiect observabil care se poate schimba în timp

3 - Compose - Starea

23

24 of 38

Transferul stării

  • Un Composable stateful poate deveni stateless dacă extragem starea din el

  • State hoisting / transferul stării
    • mutăm o stare dintr-un composable în părintele acestuia
    • => composable stateless

3 - Compose - Starea

24

25 of 38

Transferul stării - Cazuri de folosire

  • Partajăm starea între mai multe composables

  • Facem un composable stateless pentru a putea fi reutilizat în aplicație

3 - Compose - Starea

25

26 of 38

Transferul stării

  • Cel mai jos strămoș comun al componentelor care o citesc sau o scriu

  • Păstrăm starea cât mai aproape de locurile unde este folosită

  • De la proprietarul stării trebuie să dăm consumatorilor:
    • starea imutabilă și evenimentele care modifică starea

3 - Compose - Starea

26

27 of 38

Transferul stării

  • 2 parametri noi în composable:
    • value: T = valoarea de afișat
    • onValueChange: (T) -> Unit = callback lambda
      • apelat când utilizatorul schimbă valoarea

  • Părintele composable va da aceste argumente copiilor

27

28 of 38

Transferul stării - exemplu

  • Arbore de composables
  • Starea din LazyColumn folosită în celelalte composables

28

29 of 38

Transferul stării - exemplu

Starea din LazyColumn se mută în ConversationScreen

=> poate fi folosită de celelalte Composables (argument)

3 - Compose - Starea

29

30 of 38

Transferul stării - exemplu

ConversationScreen este cel mai jos strămoș comun

3 - Compose - Starea

30

31 of 38

Transferul stării - exemplu

31

32 of 38

Transferul stării - exemplu

32

33 of 38

Transferul stării - exemplu

  • Inițial starea amountInput salvată în EditNumberField

33

34 of 38

Transferul stării - exemplu

  • După mutare, composable-ul primeste valoarea (value) ca parametru și o funcție onValueChange => este stateless

34

35 of 38

Transferul stării - exemplu

  • Starea este mutată în composable-ul părinte
  • Este folosită de mai mulți copii composable

35

36 of 38

Transferul stării - exemplu

  • Am mutat starea amountInput din EditNumberField() în TipTimeLayout()
    • Părintele comun

  • EditNumberField() primeste ca argumente:
    • amountInput
    • callback lambda care actualizează amountInput

  • Astfel putem calcula și afișa valoarea tip pe baza amountInput

3 - Compose - Starea

36

37 of 38

Bibliografie

3 - Compose - Starea

37

38 of 38

Cuvinte cheie

  • Compoziție
  • Recompoziție
  • Stare
  • UI declarativ
  • remember
  • State
  • MutableState
  • Transferul stării
  • Stateless
  • Stateful

3 - Compose - Starea

38

38