In Compose puoi utilizzare le tue librerie preferite. Questa sezione descrive come incorporare alcune delle librerie più utili.
Attività
Per utilizzare Compose in un'attività, devi utilizzare
ComponentActivity
,
una sottoclasse di Activity
che fornisce il LifecycleOwner
e i componenti appropriati a Compose. Fornisce inoltre API aggiuntive che disaccoppiano il codice
dall'override dei metodi nella classe di attività.
Scrittura attività
espone queste API ai componibili in modo che non sia più necessario sostituire metodi al di fuori dei
componibili o recuperare un'istanza Activity
esplicita.
Inoltre, queste API assicurano che vengano inizializzate una sola volta, sopravvivono alla ricomposizione e puliscano correttamente se il componibile viene rimosso dalla composizione.
Risultato attività
L'API rememberLauncherForActivityResult()
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. Per avviare la richiesta, tocca il pulsante. Il lambda finale per rememberLauncherForActivityResult()
viene richiamato dopo che l'utente seleziona un'immagine e torna all'attività di avvio.
L'immagine selezionata viene caricata utilizzando la funzione rememberImagePainter()
di Coil.
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()
spiegati sopra possono essere utilizzati per
richiedere autorizzazioni di runtime
utilizzando il contratto
RequestPermission
per una singola autorizzazione o
RequestMultiplePermissions
contratto per più autorizzazioni.
La libreria delle autorizzazioni di accompagnamento può essere utilizzata anche a un livello superiore a queste API per mappare l'attuale stato concesso delle autorizzazioni sullo stato utilizzabile dalla UI di Compose.
Gestione del pulsante Indietro del sistema
Per fornire una navigazione a ritroso personalizzata e sostituire il comportamento predefinito del pulsante Indietro del sistema dall'interno dell'elemento componibile, quest'ultimo può utilizzare una BackHandler
per intercettare l'evento:
var backHandlingEnabled by remember { mutableStateOf(true) } BackHandler(backHandlingEnabled) { // Handle back press }
Il primo argomento controlla se BackHandler
è attualmente abilitato. Puoi utilizzare questo argomento per disabilitare temporaneamente il gestore in base allo stato del componente. Il lambda finale viene richiamato se l'utente attiva un evento back-end del sistema e BackHandler
è attualmente abilitato.
ViewModel
Se utilizzi la libreria ViewModel
Componenti di architettura, puoi accedere a un
ViewModel
da qualsiasi componibile
chiamando la funzione
viewModel()
.
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 nell'ambito specificato. Il valore ViewModel
viene conservato per tutto il tempo in cui l'ambito è attivo. Ad esempio,
se l'elemento componibile viene utilizzato in un'attività, viewModel()
restituisce la stessa
istanza fino al termine dell'attività o fino a quando il processo non viene terminato.
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 ) { /* ... */ }
Se il tuo ViewModel ha dipendenze, viewModel()
prende un ViewModelProvider.Factory
facoltativo come parametro.
Per ulteriori informazioni su ViewModel
in Compose e sul modo in cui le istanze vengono utilizzate
con la libreria di Navigation Compose, o con le attività e i frammenti,
consulta la documentazione sull'interoperabilità.
Flussi di dati
Compose include estensioni per le soluzioni Android basate su stream più popolari. Ognuna di queste estensioni è fornita da un artefatto 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 artefatti vengono registrati come listener e rappresentano i valori come State
. Ogni volta che viene emesso un nuovo valore, Compose ricompone le parti dell'interfaccia utente in cui viene utilizzato il valore state.value
. Ad esempio, in questo codice, ShowData
si ricompone ogni volta che
exampleLiveData
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 consente di eseguire operazioni asincrone utilizzando coroutine all'interno dei componibili.
Per saperne di più, consulta le API LaunchedEffect
, produceState
e rememberCoroutineScope
nella documentazione relativa agli effetti collaterali.
Navigazione
Il componente Navigazione fornisce supporto per le applicazioni Jetpack Compose. Per ulteriori informazioni, vedi Navigare con Compose e Eseguire la migrazione di Jetpack Navigation a Navigation Compose.
Elsa
Hilt è la soluzione consigliata per l'inserimento delle dipendenze nelle app per Android e funziona perfettamente con Compose.
La funzione viewModel()
menzionata nella sezione ViewModel utilizza automaticamente il ViewModel che Hilt crea con l'annotazione @HiltViewModel
. Abbiamo fornito la documentazione con informazioni sull'integrazione ViewModel
di Hilt.
@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() ) { /* ... */ }
Trasmissione e navigazione
Hilt si integra anche con la libreria di Navigation Compose. Aggiungi le seguenti dipendenze aggiuntive al file Gradle:
trendy
dependencies { implementation 'androidx.hilt:hilt-navigation-compose:1.0.0' }
Kotlin
dependencies { implementation("androidx.hilt:hilt-navigation-compose:1.0.0") }
Quando utilizzi Navigation Compose, utilizza sempre la funzione componibile hiltViewModel
per ottenere un'istanza di ViewModel
annotata con @HiltViewModel
.
Funziona con frammenti o attività annotati con @AndroidEntryPoint
.
Ad esempio, se ExampleScreen
è una destinazione in un grafico di navigazione, chiama hiltViewModel()
per ottenere un'istanza di ExampleViewModel
con ambito 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
con ambito a
route di navigazione o il
grafico di navigazione, utilizza la funzione componibile hiltViewModel
e trasmetti il valore
backStackEntry
corrispondente 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 paging semplifica il caricamento graduale dei dati ed è supportata in Compose.
La pagina della release
della Paging contiene informazioni sull'ulteriore dipendenza paging-compose
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 relativa a elenchi e griglie per saperne di più sull'utilizzo di Paging in Compose.
Maps
Puoi utilizzare la raccolta di 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 = MarkerState(position = singapore), title = "Singapore", snippet = "Marker in Singapore" ) } }
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Effetti collaterali in Compose
- State e Jetpack Compose
- Salvare lo stato dell'interfaccia utente in Compose