Per consentire alla tua app il controllo completo della posizione in cui disegna i contenuti, segui questi passaggi di configurazione. Senza questi passaggi, la tua app potrebbe disegnare colori neri o uniformi dietro l'interfaccia utente di sistema o non animarsi in modo sincrono con la tastiera software.
- Scegli come target Android 15 (livello API 35) o versioni successive per applicare la visualizzazione edge-to-edge su Android 15 e versioni successive. La tua app viene visualizzata dietro l'interfaccia utente di sistema. Puoi regolare l'interfaccia utente dell'app gestendo gli inset.
- Facoltativamente, chiama
enableEdgeToEdge()
inActivity.onCreate()
, che consente alla tua app di essere edge-to-edge nelle versioni precedenti di Android. Imposta
android:windowSoftInputMode="adjustResize"
nella voceAndroidManifest.xml
della tua attività. Questa impostazione consente all'app di ricevere le dimensioni dell'IME software come margini interni, il che ti aiuta ad applicare il layout e la spaziatura interna appropriati quando l'IME viene visualizzato e scompare nell'app.<!-- In your AndroidManifest.xml file: --> <activity android:name=".ui.MainActivity" android:label="@string/app_name" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.MyApplication" android:exported="true">
Utilizzare le API Compose
Una volta che l'attività ha preso il controllo della gestione di tutti gli inserti, puoi utilizzare le API Compose per assicurarti che i contenuti non siano oscurati e che gli elementi interattivi non si sovrappongano all'interfaccia utente di sistema. Queste API sincronizzano anche il layout dell'app con le modifiche all'inset.
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 due modi principali per utilizzare questi tipi di rientro per regolare i layout composabili: modificatori di spaziatura interna e modificatori delle dimensioni del rientro.
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 spaziatura interna. Quando si approfondisce l'albero di composizione, i modificatori di spaziatura interna
nidificati e i modificatori di dimensione dell'inset sanno che una parte degli
inset è già stata utilizzata dai modificatori di spaziatura interna esterni ed evitano
di utilizzare la stessa parte degli inset 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 avere l'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 alcun padding,
non vengono utilizzati inset 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 padding 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 insets. 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 del
lato inferiore delle barre di sistema, finché Spacer
non corrisponde all'altezza del
lato 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. È utile in combinazione con i modificatori delle dimensioni
dell'inset, per indicare ai fratelli che una determinata quantità di inset è
già stata consumata:
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 in genere utilizza un valore degli inserti in ritardo di un fotogramma. 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.