Una volta che l'attività ha preso il controllo della gestione di tutti gli inset, puoi utilizzare le API Compose per verificare che i contenuti non siano oscurati e che gli elementi interattivi non si sovrappongano all'interfaccia utente del sistema. Queste API sincronizzano anche il layout dell'app con le modifiche all'inset.
Gestire gli inset utilizzando modificatori di padding o dimensioni
Ad esempio, questo è il metodo più semplice per applicare gli inset ai contenuti dell'intera app:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
Questo snippet applica gli inserti della finestra safeDrawing come spaziatura interna intorno all'intero contenuto dell'app. Sebbene ciò garantisca che gli elementi interattivi non si sovrappongano all'interfaccia utente di sistema, significa anche che nessuna parte dell'app verrà disegnata dietro l'interfaccia utente di sistema per ottenere un effetto da bordo a bordo. Per sfruttare al meglio l'intera finestra, devi perfezionare il punto in cui vengono applicati gli inset su base schermo per schermo o componente per componente.
Tutti questi tipi di rientro vengono animati automaticamente con le animazioni IME di cui è stato eseguito il backporting all'API 21. Di conseguenza, anche tutti i layout che utilizzano questi rientri vengono animati automaticamente al variare dei valori dei rientri.
Esistono tre modi per gestire gli inset per regolare i layout di composizione:
Modificatori di spaziatura interna
Modifier.windowInsetsPadding(windowInsets: WindowInsets) applica
i margini della finestra specificati come spaziatura interna, proprio come farebbe Modifier.padding.
Ad esempio, Modifier.windowInsetsPadding(WindowInsets.safeDrawing) applica
i margini di sicurezza per il disegno come spaziatura interna su tutti e quattro i lati.
Esistono anche diversi metodi di utilità integrati per i tipi di rientro più comuni.
Modifier.safeDrawingPadding() è uno di questi metodi, equivalente a
Modifier.windowInsetsPadding(WindowInsets.safeDrawing). Esistono modificatori
analoghi per gli altri tipi di rientro.
Modificatori delle dimensioni dell'inserto
I seguenti modificatori applicano una quantità di rientri della finestra impostando le dimensioni del componente in modo che corrispondano alle dimensioni dei rientri:
Applica il lato iniziale di windowInsets come larghezza (come |
|
Applica il lato finale di windowInsets come larghezza (come |
|
Applica il lato superiore di windowInsets come altezza (come |
|
|
Applica il lato inferiore di windowInsets come altezza (come |
Questi modificatori sono particolarmente utili per dimensionare un Spacer che occupa lo spazio dei rientri:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Consumo inserto
I modificatori di spaziatura interna (windowInsetsPadding e helper come
safeDrawingPadding) utilizzano automaticamente la porzione di spaziatura interna
applicata come padding. Quando si approfondisce l'albero di composizione, i modificatori di spaziatura interna
e i modificatori di dimensione dell'insetto sanno che una parte degli
insetti è già stata utilizzata dai modificatori di spaziatura interna esterni ed evitano
di utilizzare la stessa parte degli insetti più di una volta, il che comporterebbe uno spazio
aggiuntivo eccessivo.
I modificatori delle dimensioni dell'insetto evitano inoltre di utilizzare la stessa porzione di insetti più di una volta se gli insetti sono già stati consumati. Tuttavia, poiché modificano direttamente le dimensioni, non consumano gli inset stessi.
Di conseguenza, i modificatori di padding nidificati modificano automaticamente la quantità di padding applicato a ogni elemento componibile.
Se esaminiamo lo stesso esempio di LazyColumn di prima, le dimensioni di LazyColumn vengono
modificate dal modificatore imePadding. All'interno di LazyColumn, l'ultimo elemento è
dimensionato in modo da corrispondere all'altezza della parte inferiore delle barre di sistema:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Quando l'IME è chiuso, il modificatore imePadding() non applica alcun riempimento, poiché
l'IME non ha altezza. Poiché il modificatore imePadding() non applica spaziatura interna,
non vengono utilizzati rientri e l'altezza di Spacer corrisponderà alla dimensione
del lato inferiore delle barre di sistema.
Quando si apre l'IME, i relativi rientri vengono animati in modo che corrispondano alle dimensioni dell'IME e il
modificatore imePadding() inizia ad applicare il riempimento inferiore per ridimensionare
LazyColumn all'apertura dell'IME. Quando il modificatore imePadding() inizia ad applicare
il padding inferiore, inizia anche a utilizzare la quantità di margini interni. Pertanto, l'altezza di Spacer inizia a diminuire, in quanto parte della spaziatura per le barre di sistema è già stata applicata dal modificatore imePadding(). Una volta che il modificatore
imePadding() applica un riempimento inferiore maggiore
delle barre di sistema, l'altezza di Spacer è zero.
Quando l'IME si chiude, le modifiche avvengono al contrario: Spacer inizia a
espandersi da un'altezza pari a zero una volta che imePadding() applica meno della
parte inferiore delle barre di sistema, finché Spacer non corrisponde all'altezza della
parte inferiore delle barre di sistema una volta che l'IME è completamente animato.
TextField.Questo comportamento si ottiene tramite la comunicazione tra tutti i modificatori
windowInsetsPadding e può essere influenzato in un paio di altri
modi.
Modifier.consumeWindowInsets(insets: WindowInsets) consuma anche gli inset allo stesso modo di Modifier.windowInsetsPadding, ma non applica gli inset consumati come padding. Questa proprietà è utile in combinazione con i modificatori delle dimensioni
dell'inset, per indicare ai fratelli che una determinata quantità di inset è
già stata utilizzata:
Column(Modifier.verticalScroll(rememberScrollState())) { Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars)) Column( Modifier.consumeWindowInsets( WindowInsets.systemBars.only(WindowInsetsSides.Vertical) ) ) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) }
Modifier.consumeWindowInsets(paddingValues: PaddingValues) si comporta in modo molto simile alla versione con un argomento WindowInsets, ma richiede un PaddingValues arbitrario da utilizzare. Ciò è utile per informare
i bambini quando il padding o la spaziatura sono forniti da un meccanismo diverso dai
modificatori di padding interno, ad esempio un Modifier.padding ordinario o distanziatori
ad altezza fissa:
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
Nei casi in cui sono necessari gli inset grezzi della finestra senza consumo, utilizza direttamente i valori WindowInsets o utilizza WindowInsets.asPaddingValues() per restituire un PaddingValues degli inset non interessati dal consumo.
Tuttavia, a causa dei seguenti avvisi, preferisci utilizzare i modificatori di padding degli inserti della finestra e i modificatori delle dimensioni degli inserti della finestra, ove possibile.
Inset e fasi di Jetpack Compose
Compose utilizza le API AndroidX di base per aggiornare e animare gli inset, che utilizzano le API della piattaforma sottostanti che gestiscono gli inset. A causa del comportamento della piattaforma, gli inset hanno una relazione speciale con le fasi di Jetpack Compose.
Il valore degli inserti viene aggiornato dopo la fase di composizione, ma prima della fase di layout. Ciò significa che la lettura del valore degli inserti nella composizione generalmente utilizza un valore degli inserti in ritardo di un frame. I modificatori incorporati descritti in questa pagina sono progettati per ritardare l'utilizzo dei valori dei margini interni fino alla fase di layout, il che garantisce che i valori dei margini interni vengano utilizzati nello stesso frame in cui vengono aggiornati.