Puoi utilizzare le tue librerie preferite in Scrivi. Questa sezione descrive come incorporare alcune delle librerie più utili.
Attività
Per utilizzare Compose in un'attività, devi usare
ComponentActivity
,
una sottoclasse di Activity
che fornisce i valori LifecycleOwner
e
componenti in Compose. Fornisce inoltre API aggiuntive che disaccoppiano il codice
dai metodi di override nella tua classe di attività.
Scrittura attività
espone queste API agli elementi componibili, in modo che l'override dei metodi al di fuori del
componibili o il recupero di un'istanza Activity
esplicita non è più necessario.
Inoltre, queste API assicurano di essere inizializzate una sola volta, di sopravvivere alla ricompozione e di essere ripulite correttamente se il composable viene rimosso dalla composizione.
Risultato attività
La
rememberLauncherForActivityResult()
API ti consente di
ottenere un risultato da un'attività
nel tuo componibile:
@Composable fun GetContentExample() { var imageUri by remember { mutableStateOf<Uri?>(null) } val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? -> imageUri = uri } Column { Button(onClick = { launcher.launch("image/*") }) { Text(text = "Load Image") } Image( painter = rememberAsyncImagePainter(imageUri), contentDescription = "My Image" ) } }
Questo esempio mostra un contratto
GetContent()
semplice. Toccando il pulsante viene avviata la richiesta. La lambda finale per
rememberLauncherForActivityResult()
viene invocata quando l'utente seleziona un'immagine e torna all'attività di lancio.
L'immagine selezionata viene caricata utilizzando rememberImagePainter()
di Coil
personalizzata.
Qualsiasi sottoclasse di
ActivityResultContract
può essere utilizzata come primo argomento di
rememberLauncherForActivityResult()
.
Ciò significa che puoi utilizzare questa tecnica per richiedere contenuti dal framework
e in altri pattern comuni. Puoi anche creare i tuoi
contratti personalizzati e utilizzarli con
questa tecnica.
Richiesta di autorizzazioni di runtime
La stessa API Activity Result e
rememberLauncherForActivityResult()
spiegate sopra possono essere utilizzate per
richiedere le autorizzazioni di runtime
utilizzando il contratto
RequestPermission
per una singola autorizzazione o
RequestMultiplePermissions
per più autorizzazioni.
La Libreria delle autorizzazioni di partecipazione puoi anche utilizzare un livello superiore a queste API per mappare lo stato concesso attuale le autorizzazioni nello stato utilizzabile dall'interfaccia utente di Compose.
Gestione del pulsante Indietro del sistema
Per fornire la navigazione a ritroso personalizzata
e sostituire il comportamento predefinito del pulsante Indietro di sistema dall'interno del
composable, il composable può utilizzare un
BackHandler
per intercettare l'evento:
var backHandlingEnabled by remember { mutableStateOf(true) } BackHandler(backHandlingEnabled) { // Handle back press }
Il primo argomento controlla se il gestore
BackHandler
è attualmente attivo. Puoi utilizzare questo argomento per disattivare temporaneamente il gestore
in base allo stato del componente. La lambda finale verrà invocata se l'utente attiva un evento di ritorno di sistema e BackHandler
è attualmente attivo.
ViewModel
Se utilizzi la libreria Architecture Components
ViewModel, puoi accedere a un
ViewModel
da qualsiasi composable chiamando la funzione
viewModel()
. Aggiungi la seguente dipendenza al file Gradle:
Groovy
dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5' }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.5") }
A questo punto, puoi utilizzare la funzione viewModel()
nel codice.
class MyViewModel : ViewModel() { /*...*/ } // import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyScreen( viewModel: MyViewModel = viewModel() ) { // use viewModel here }
viewModel()
restituisce un ViewModel
esistente o ne crea uno nuovo. Per impostazione predefinita,
ViewModel
restituito è limitato all'attività, al frammento o alla destinazione di navigazione che lo contiene e viene mantenuto attivo finché l'ambito è attivo.
Ad esempio, se il componibile viene utilizzato in un'attività, viewModel()
restituisce il
la stessa istanza fino al termine dell'attività o fino all'interruzione del processo.
class MyViewModel : ViewModel() { /*...*/ } // import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyScreen( // Returns the same instance as long as the activity is alive, // just as if you grabbed the instance from an Activity or Fragment viewModel: MyViewModel = viewModel() ) { /* ... */ } @Composable fun MyScreen2( viewModel: MyViewModel = viewModel() // Same instance as in MyScreen ) { /* ... */ }
Linee guida per l'utilizzo
In genere accedi a ViewModel
istanze a livello di schermo
componibili, cioè vicini a un componibile radice chiamato da un'attività,
frammento o la destinazione di un grafico di navigazione. Questo perché ViewModel
s
sono, per impostazione predefinita, limitati a questi oggetti a livello di schermata. Scopri di più sul
ciclo di vita e sull'ambito di un
ViewModel
qui.
Cerca di non trascurare
ViewModel
di istanze ad altri componibili, in quanto ciò può rendere tali elementi componibili
più difficili da testare e possono danneggiare
anteprime. Passa invece solo i dati
e le funzioni di cui hanno bisogno come parametri.
Puoi utilizzare ViewModel
istanze per
gestisci lo stato per gli elementi componibili a livello di schermo secondario, tuttavia, tieni presente
di ViewModel
ciclo di vita e ambito. Se il composable è autonomo, ti consigliamo di utilizzare Hilt per iniettare ViewModel
per evitare di dover passare le dipendenze dai composable di primo livello.
Se ViewModel
ha dipendenze, viewModel()
accetta un parametro facoltativo
ViewModelProvider.Factory
.
Per saperne di più su ViewModel
in Compose e su come vengono utilizzate le istanze
con la libreria Navigation Compose o con attività e frammenti
consulta la documentazione sull'interoperabilità.
Flussi di dati
Compose è dotato di estensioni per le soluzioni basate su stream più diffuse di Android. Ognuna di queste estensioni è fornita da un elemento diverso:
LiveData.observeAsState()
incluso nell'elementoandroidx.compose.runtime:runtime-livedata:$composeVersion
.Flow.collectAsState()
non richiede dipendenze aggiuntive.Observable.subscribeAsState()
incluso nell'elementoandroidx.compose.runtime:runtime-rxjava2:$composeVersion
oandroidx.compose.runtime:runtime-rxjava3:$composeVersion
.
Questi elementi vengono registrati come ascoltatori e rappresentano i valori come
State
. Ogni volta che un nuovo valore
viene emesso, Compose ricompone le parti della UI in cui viene emesso state.value
in uso. Ad esempio, in questo codice, ShowData
si ricomponie ogni volta cheexampleLiveData
emette un nuovo valore.
// import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyScreen( viewModel: MyViewModel = viewModel() ) { val dataExample = viewModel.exampleLiveData.observeAsState() // Because the state is read here, // MyScreen recomposes whenever dataExample changes. dataExample.value?.let { ShowData(dataExample) } }
Operazioni asincrone in Compose
Jetpack Compose ti consente di eseguire operazioni asincrone utilizzando le coroutine all'interno dei componibili.
Visualizza le API LaunchedEffect
, produceState
e rememberCoroutineScope
in
la documentazione relativa agli effetti collaterali per ulteriori informazioni
informazioni.
Navigazione
Il componente Navigazione fornisce supporto per le applicazioni Jetpack Compose. Per ulteriori informazioni, consulta Navigare con Compose e Eseguire la migrazione di Jetpack Navigation a Navigation Compose.
Elsa
Hilt è la soluzione consigliata per l'iniezione di dipendenze nelle app per Android e funziona perfettamente con Compose.
La funzione viewModel()
menzionata nella sezione ViewModel
utilizza automaticamente il ViewModel creato da Hilt con @HiltViewModel
annotazione. Abbiamo fornito la documentazione con informazioni sul ViewModel di Hilt
integrazione.
@HiltViewModel class MyViewModel @Inject constructor( private val savedStateHandle: SavedStateHandle, private val repository: ExampleRepository ) : ViewModel() { /* ... */ } // import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyScreen( viewModel: MyViewModel = viewModel() ) { /* ... */ }
Escursionismo e navigazione
Hilt si integra anche con la libreria Navigation Compose. Aggiungi quanto segue ulteriori dipendenze al tuo file Gradle:
Groovy
dependencies { implementation 'androidx.hilt:hilt-navigation-compose:1.2.0' }
Kotlin
dependencies { implementation("androidx.hilt:hilt-navigation-compose:1.2.0") }
Quando utilizzi Navigation Compose, usa sempre la funzione composable hiltViewModel
per ottenere un'istanza del tuo @HiltViewModel
annotato ViewModel
.
Questa operazione è valida per i frammenti o le attività annotati con
@AndroidEntryPoint
.
Ad esempio, se ExampleScreen
è una destinazione in un grafico di navigazione,
chiama hiltViewModel()
per ottenere un'istanza con ambito ExampleViewModel
alla destinazione, come mostrato nello snippet di codice riportato di seguito:
// import androidx.hilt.navigation.compose.hiltViewModel @Composable fun MyApp() { val navController = rememberNavController() val startRoute = "example" NavHost(navController, startDestination = startRoute) { composable("example") { backStackEntry -> // Creates a ViewModel from the current BackStackEntry // Available in the androidx.hilt:hilt-navigation-compose artifact val viewModel = hiltViewModel<MyViewModel>() MyScreen(viewModel) } /* ... */ } }
Se invece devi recuperare l'istanza di un ViewModel
limitata ai percorsi di navigazione o al grafo di navigazione, utilizza la funzione componibile hiltViewModel
e passa il corrispondente backStackEntry
come parametro:
// import androidx.hilt.navigation.compose.hiltViewModel // import androidx.navigation.compose.getBackStackEntry @Composable fun MyApp() { val navController = rememberNavController() val startRoute = "example" val innerStartRoute = "exampleWithRoute" NavHost(navController, startDestination = startRoute) { navigation(startDestination = innerStartRoute, route = "Parent") { // ... composable("exampleWithRoute") { backStackEntry -> val parentEntry = remember(backStackEntry) { navController.getBackStackEntry("Parent") } val parentViewModel = hiltViewModel<ParentViewModel>(parentEntry) ExampleWithRouteScreen(parentViewModel) } } } }
Paging
La libreria di Paginazione consente di caricare più facilmente i dati gradualmente ed è supportata in Componi.
La pagina di release della paginazione contiene informazioni sulla dipendenza paging-compose
aggiuntiva che deve essere aggiunta al progetto e alla relativa versione.
Ecco un esempio delle API Compose della libreria di paging:
@Composable fun MyScreen(flow: Flow<PagingData<String>>) { val lazyPagingItems = flow.collectAsLazyPagingItems() LazyColumn { items( lazyPagingItems.itemCount, key = lazyPagingItems.itemKey { it } ) { index -> val item = lazyPagingItems[index] Text("Item is $item") } } }
Consulta la documentazione su elenchi e griglie per saperne di più sull'utilizzo della paginazione in Compose.
Maps
Puoi utilizzare la libreria Maps Compose per fornire Google Maps nella tua app. Ecco un esempio di utilizzo:
@Composable fun MapsExample() { val singapore = LatLng(1.35, 103.87) val cameraPositionState = rememberCameraPositionState { position = CameraPosition.fromLatLngZoom(singapore, 10f) } GoogleMap( modifier = Modifier.fillMaxSize(), cameraPositionState = cameraPositionState ) { Marker( state = remember { MarkerState(position = singapore) }, title = "Singapore", snippet = "Marker in Singapore" ) } }
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Effetti collaterali in Componi
- State e Jetpack Compose
- Salva lo stato della UI in Compose