In Compose, puoi concatenare più modificatori per modificare l'aspetto e l'aspetto di un componibile. Queste catene di modificatori possono influenzare i vincoli passati ai componibili, che definiscono i limiti di larghezza e altezza.
Questa pagina descrive in che modo i modificatori concatenati influenzano i vincoli e, a loro volta, la misurazione e il posizionamento degli elementi componibili.
Modificatori nell'albero dell'interfaccia utente
Per capire in che modo i modificatori si influenzano a vicenda, è utile visualizzare come vengono visualizzati nell'albero dell'interfaccia utente, generato durante la fase di composizione. Per ulteriori informazioni, consulta la sezione Composizione.
Nella struttura ad albero dell'interfaccia utente, puoi visualizzare i modificatori come nodi wrapper per i nodi di layout:
L'aggiunta di più modificatori a un componibile crea una catena di modificatori. Quando concateni più modificatori, ogni nodo di modifica aggrega il resto della catena e il nodo di layout al suo interno. Ad esempio, se concateni clip
e un modificatore
size
, il nodo del modificatore clip
inserisce un a capo nel nodo del modificatore size
, che a sua volta aggrega il nodo di layout Image
.
Nella fase di layout, l'algoritmo che cammina nell'albero rimane invariato, ma viene visitato anche ogni nodo di modifica. In questo modo, un modificatore può cambiare i requisiti di dimensione e il posizionamento del modificatore o del nodo di layout.
Come mostrato nella Figura 2, l'implementazione degli elementi componibili Image
e Text
in sé consiste in una catena di modificatori che avvolgono un singolo nodo di layout. Le implementazioni di Row
e Column
sono semplicemente nodi di layout che descrivono come strutturare i nodi figlio.
Riassumendo:
- I modificatori aggregano un singolo modificatore o nodo di layout.
- I nodi di layout possono disporre più nodi secondari.
Le seguenti sezioni descrivono come usare questo modello mentale per ragionare sul concatenamento dei modificatori e su come questo influenza le dimensioni dei componibili.
Vincoli nella fase di layout
La fase di layout segue un algoritmo in tre passaggi per trovare la larghezza, l'altezza e le coordinate x e y di ogni nodo di layout:
- Misurare gli elementi secondari: un nodo misura gli eventuali elementi figlio.
- Stabilisci la dimensione personalizzata: in base a queste misurazioni, un nodo decide la propria dimensione.
- Posiziona elementi figlio: ogni nodo figlio viene posizionato in relazione alla posizione di un nodo.
Constraints
aiuta a trovare le dimensioni giuste per i nodi durante i primi due passaggi dell'algoritmo. I vincoli definiscono i limiti minimo e massimo per la larghezza e l'altezza di un nodo. Quando è il nodo a decidere le sue dimensioni, la dimensione misurata deve rientrare in questo intervallo.
Tipi di vincoli
Un vincolo può essere uno dei seguenti:
- Associato: il nodo ha larghezza e altezza massime e minime.
- Non limitato: il nodo non è vincolato a nessuna dimensione. I limiti massimi di larghezza e altezza sono impostati su infinito.
- Esatta: il nodo deve rispettare un requisito di dimensioni esatto. I limiti minimo e massimo sono impostati sullo stesso valore.
- Combinazione: il nodo segue una combinazione dei tipi di vincolo precedenti. Ad esempio, un vincolo può limitare la larghezza consentendo un'altezza massima illimitata oppure impostare una larghezza esatta, ma fornire un'altezza limitata.
La sezione successiva descrive il modo in cui questi vincoli vengono trasferiti da un elemento padre a uno secondario.
Come passare i vincoli da un elemento padre all'altro
Durante il primo passaggio dell'algoritmo descritto in Vincoli nella fase di layout, i vincoli vengono trasmessi da padre a figlio nella struttura ad albero dell'interfaccia utente.
Quando un nodo padre misura i suoi figli, fornisce questi vincoli a ciascuno per indicare quanto possono essere grandi o piccoli che possono essere. Poi, quando decide le proprie dimensioni, aderisce anche ai vincoli trasmessi dai genitori.
A livello generale, l'algoritmo funziona nel seguente modo:
- Per decidere le dimensioni effettive che intende occupare, il nodo radice nell'albero dell'interfaccia utente misura i relativi elementi secondari e inoltra gli stessi vincoli al primo elemento figlio.
- Se l'elemento figlio è un modificatore che non influisce sulla misurazione, inoltra i vincoli al modificatore successivo. I vincoli vengono trasmessi dalla catena di modificatori così com'è, a meno che non venga raggiunto un modificatore che influisce sulla misurazione. I vincoli vengono quindi ridimensionati di conseguenza.
- Quando viene raggiunto un nodo che non ha elementi secondari (chiamato "nodo foglia "), ne decide le dimensioni in base ai vincoli che sono stati trasmessi e restituisce questa dimensione risolta all'elemento padre.
- L'elemento principale adatta i propri vincoli in base alle misurazioni di questo asset secondario e richiama l'elemento secondario successivo con questi vincoli regolati.
- Dopo aver misurato tutti i figli di un nodo, il nodo padre decide le proprie dimensioni e le comunica al proprio padre.
- In questo modo, l'intero albero viene attraversato in profondità. Alla fine, tutti i nodi hanno deciso le proprie dimensioni e la fase di misurazione è stata completata.
Per un esempio dettagliato, guarda il video Vincoli e ordine dei modificatori.
Modificatori che influiscono sui vincoli
Nella sezione precedente hai imparato che alcuni modificatori possono influire sulla dimensione del vincolo. Le seguenti sezioni descrivono modificatori specifici che influiscono sui vincoli.
Modificatore size
Il modificatore size
dichiara le dimensioni preferite dei contenuti.
Ad esempio, la seguente struttura dell'interfaccia utente dovrebbe essere visualizzata in un container 300dp
entro 200dp
. I vincoli sono limitati e consentono larghezze comprese tra 100dp
e 300dp
e altezze comprese tra 100dp
e 200dp
:
Il modificatore size
adatta i vincoli in entrata in modo che corrispondano al valore che gli viene trasmesso.
In questo esempio, il valore è 150dp
:
Se la larghezza e l'altezza sono minori del limite del vincolo minimo o maggiore del limite del vincolo più grande, il modificatore corrisponde il più fedelmente possibile ai vincoli passati, pur rispettando i vincoli passati:
Tieni presente che il concatenamento di più modificatori size
non funziona. Il primo modificatore di size
imposta i vincoli minimo e massimo su un valore fisso. Anche se
il secondo modificatore di dimensione richiede una dimensione inferiore o superiore, deve comunque rispettare
i limiti esatti trasmessi, quindi non sostituirà questi valori:
Modificatore requiredSize
Utilizza il modificatore requiredSize
anziché size
se hai bisogno che il nodo esegua l'override dei vincoli in entrata. Il modificatore requiredSize
sostituisce i vincoli in entrata e trasmette le dimensioni specificate come limiti esatti.
Quando le dimensioni vengono passate di nuovo all'albero, il nodo figlio sarà centrato nello spazio disponibile:
Modificatori width
e height
Il modificatore size
adatta sia la larghezza sia l'altezza dei vincoli. Con
il modificatore width
, puoi impostare una larghezza fissa, ma lasciare indeciso l'altezza.
Analogamente, con il modificatore height
puoi impostare un'altezza fissa, ma lasciare indecisa la larghezza:
Modificatore sizeIn
Il modificatore sizeIn
consente di impostare vincoli minimi e massimi esatti per larghezza e altezza. Utilizza il modificatore sizeIn
se hai bisogno di un controllo granulare sui vincoli.
Esempi
Questa sezione mostra e spiega l'output di diversi snippet di codice con modificatori concatenati.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
Questo snippet produce il seguente output:
- Il modificatore
fillMaxSize
modifica i vincoli per impostare la larghezza e l'altezza minime sul valore massimo, ovvero300dp
per larghezza e200dp
per altezza. - Anche se il modificatore
size
vuole utilizzare una dimensione pari a50dp
, deve comunque rispettare i vincoli minimi previsti. Di conseguenza, il modificatoresize
restituirà anche gli esatti limiti del vincolo di300
entro il campo200
, ignorando di fatto il valore fornito nel modificatoresize
. Image
segue questi limiti e segnala una dimensione pari a300
per200
, che viene passata fino in fondo all'albero.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
Questo snippet produce il seguente output:
- Il modificatore
fillMaxSize
adatta i vincoli per impostare la larghezza e l'altezza minime sul valore massimo, ovvero300dp
per la larghezza e200dp
per l'altezza. - Il modificatore
wrapContentSize
reimposta i vincoli minimi. Quindi, sebbenefillMaxSize
abbia generato vincoli fissi,wrapContentSize
lo reimposta nuovamente ai vincoli limitati. Il nodo seguente può ora occupare di nuovo l'intero spazio o essere più piccolo dell'intero spazio. - Il modificatore
size
imposta i vincoli sui limiti minimo e massimo di50
. - Il valore
Image
viene risolto in50
in base alla dimensione50
e il modificatoresize
la inoltra. - Il modificatore
wrapContentSize
ha una proprietà speciale. Prende il figlio e lo colloca al centro dei limiti minimi disponibili che gli sono stati passati. Le dimensioni che comunica ai suoi elementi padre corrispondono quindi ai limiti minimi che sono stati passati al suo interno.
Combinando solo tre modificatori, puoi definire una dimensione per l'elemento componibile e centrarla nel relativo elemento padre.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
Questo snippet produce il seguente output:
- Il modificatore
clip
non cambia i vincoli.- Il modificatore
padding
abbassa i vincoli massimi. - Il modificatore
size
imposta tutti i vincoli su100dp
. Image
rispetta questi vincoli e segnala una dimensione pari a100
entro il giorno100dp
.- Il modificatore
padding
aggiunge10dp
per tutte le dimensioni, in modo da aumentare la larghezza e l'altezza segnalate di20dp
. - In fase di disegno, il modificatore
clip
agisce su un canvas di120
di120dp
. Viene quindi creata una maschera circolare di quelle dimensioni. - Il modificatore
padding
inserisce quindi i propri contenuti in base a10dp
in tutte le dimensioni, riducendo così le dimensioni della tela a100
di100dp
. - Il
Image
è disegnato nella tela. L'immagine è ritagliata in base al cerchio originale di120dp
, quindi l'output è un risultato non arrotondato.
- Il modificatore