1 of 37

Tehnici avansate pentru

dezvoltarea aplicațiilor mobile

3 - Compose - Starea

2 of 37

Starea și compoziția

2

3 of 37

Fazele Compose

  • 3 faze pentru afișarea UI-ului
    • Compoziția - rulate Composables => descriere a UI-ului
    • Layout - măsurare și plasare
    • Desenarea - randarea

3

4 of 37

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 37

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 37

Compoziția

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

6

7 of 37

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 37

Câmp text - fără actualizare

8

9 of 37

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 37

Salvarea stării

Starea = un obiect observabil salvat în Compoziție

10

11 of 37

by

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

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

3 - Compose - Starea

11

12 of 37

remember

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

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

3 - Compose - Starea

12

13 of 37

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 37

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 37

mutableStateOf

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

  • Orice modificare a lui value => recompoziție a tuturor Composables care citesc value

3 - Compose - Starea

15

16 of 37

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 37

Salvarea stării - exemplu

3 - Compose - Starea

17

18 of 37

Salvarea stării - exemplu

  • Variabila name este salvată într-un obiect observabil
    • 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

18

19 of 37

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

19

20 of 37

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

20

21 of 37

Transferul stării

21

22 of 37

Composable 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

3 - Compose - Starea

22

23 of 37

State Hoisting

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

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

3 - Compose - Starea

23

24 of 37

State Hoisting - Cazuri de folosire

  • 1) Partajăm starea între mai multe composables

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

3 - Compose - Starea

24

25 of 37

State Hoisting

  • Mutăm starea în cel mai jos strămoș comun al componentelor care o citesc sau o scriu
    • Cât mai aproape de locurile unde este folosită

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

3 - Compose - Starea

25

26 of 37

State Hoisting

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

  • Părintele composable va da aceste argumente copiilor

26

27 of 37

State Hoisting - exemplu

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

27

28 of 37

State Hoisting - exemplu

Starea din LazyColumn se mută în ConversationScreen

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

3 - Compose - Starea

28

29 of 37

State Hoisting - exemplu

ConversationScreen este cel mai jos strămoș comun

3 - Compose - Starea

29

30 of 37

State Hoisting - exemplu

30

31 of 37

State Hoisting - exemplu

31

32 of 37

State Hoisting - exemplu

  • Inițial starea amountInput salvată în EditNumberField

32

33 of 37

State Hoisting - exemplu

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

33

34 of 37

State Hoisting - exemplu

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

34

35 of 37

State Hoisting - 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

35

36 of 37

Bibliografie

3 - Compose - Starea

36

37 of 37

Cuvinte cheie

  • Compoziție
  • Recompoziție
  • Stare
  • UI declarativ
  • remember
  • State
  • MutableState
  • State Hoisting
  • Stateless
  • Stateful

3 - Compose - Starea

37

37