Sie können Ihre bevorzugten Bibliotheken in Compose verwenden. In diesem Abschnitt wird beschrieben, wie Sie einige der nützlichsten Bibliotheken einbinden.
Aktivität
Wenn Sie Compose in einer Activity verwenden möchten, müssen Sie
ComponentActivity,
eine abgeleitete Klasse von Activity verwenden, die den entsprechenden LifecycleOwner und
Komponenten für Compose bereitstellt. Außerdem bietet sie zusätzliche APIs, mit denen Sie Ihren Code von überschreibenden Methoden in Ihrer Aktivitätsklasse entkoppeln können.
Activity Compose
stellt diese APIs für Composables bereit, sodass überschreibende Methoden außerhalb Ihrer
Composables oder das Abrufen einer expliziten Activity Instanz nicht mehr erforderlich sind.
Darüber hinaus sorgen diese APIs dafür, dass sie nur einmal initialisiert werden, die Neukomposition überstehen und ordnungsgemäß bereinigt werden, wenn die komponierbare Funktion aus der Komposition entfernt wird.
Aktivitätsergebnis
Die
rememberLauncherForActivityResult()
API ermöglicht es Ihnen,
ein Ergebnis von einer Aktivität
in Ihrem Composable abzurufen:
@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" ) } }
In diesem Beispiel wird ein einfacher
GetContent()
Vertrag veranschaulicht. Durch Tippen auf die Schaltfläche wird die Anfrage gestartet. Die nachgestellte Lambda-Funktion für
rememberLauncherForActivityResult()
wird aufgerufen, sobald der Nutzer ein Bild auswählt und zur startenden Aktivität zurückkehrt.
Dadurch wird das ausgewählte Bild mit der Funktion rememberImagePainter() von Coil geladen.
Jede abgeleitete Klasse von
ActivityResultContract
kann als erstes Argument für
rememberLauncherForActivityResult()verwendet werden.
Das bedeutet, dass Sie dieses Verfahren verwenden können, um Inhalte aus dem Framework und in anderen gängigen Mustern anzufordern. Sie können auch eigene
benutzerdefinierte Verträge erstellen und mit
dieser Technik verwenden.
Laufzeitberechtigungen anfordern
Dieselbe Activity Result API und
rememberLauncherForActivityResult()
, die oben beschrieben wurden, können verwendet werden, um
Laufzeitberechtigungen
mit dem
RequestPermission
Vertrag für eine einzelne Berechtigung oder dem
RequestMultiplePermissions
Vertrag für mehrere Berechtigungen anzufordern.
Die Accompanist Permissions-Bibliothek kann auch als Ebene über diesen APIs verwendet werden, um den aktuellen gewährten Status für Berechtigungen in einen Status zu übertragen, der von Ihrer Compose-UI verwendet werden kann.
Systemschaltfläche „Zurück“ verarbeiten
Wenn Sie eine benutzerdefinierte Rückwärtsnavigation bereitstellen und das Standardverhalten des System-Buttons „Zurück“ in Ihrer komponierbaren Funktion überschreiben möchten, kann Ihre komponierbare Funktion ein BackHandler verwenden, um dieses Ereignis abzufangen:
var backHandlingEnabled by remember { mutableStateOf(true) } BackHandler(backHandlingEnabled) { // Handle back press }
Das erste Argument steuert, ob die
BackHandler
derzeit aktiviert ist. Sie können dieses Argument verwenden, um Ihren Handler
basierend auf dem Status Ihrer Komponente vorübergehend zu deaktivieren. Die nachgestellte Lambda-Funktion wird aufgerufen, wenn der
Nutzer ein Systemereignis „Zurück“ auslöst und die
BackHandler
derzeit aktiviert ist.
ViewModel
Wenn Sie die Architecture Components
ViewModel-Bibliothek verwenden, können Sie über die
Funktion
viewModel()von jedem Composable aus auf ein
ViewModelzugreifen. Fügen Sie Ihrer Gradle-Datei die folgende Abhängigkeit hinzu:
Groovy
dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0' }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0") }
Anschließend können Sie die Funktion viewModel() in Ihrem Code verwenden.
class MyViewModel : ViewModel() { /*...*/ } // import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyScreen( viewModel: MyViewModel = viewModel() ) { // use viewModel here }
viewModel() gibt ein vorhandenes ViewModel zurück oder erstellt ein neues. Standardmäßig ist das zurückgegebene ViewModel auf die umschließende Aktivität, das Fragment oder das Navigationsziel beschränkt und bleibt so lange erhalten, wie der Bereich aktiv ist.
Wenn das Composable beispielsweise in einer Aktivität verwendet wird, gibt viewModel() dieselbe Instanz zurück, bis die Aktivität beendet oder der Prozess beendet wird.
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 ) { /* ... */ }
Nutzungsrichtlinien
Sie greifen in der Regel auf ViewModel-Instanzen in Composables auf Bildschirmebene zu, d. h. in der Nähe eines Root-Composables, das von einer Aktivität, einem Fragment oder einem Ziel eines Navigationsdiagramms aufgerufen wird. Das liegt daran, dass ViewModels standardmäßig auf diese Objekte auf Bildschirmebene beschränkt sind. Weitere Informationen zum
ViewModel Lebenszyklus und Bereich von
finden Sie hier.
Vermeiden Sie es,
ViewModelInstanzen an andere Composables zu übergeben, da dies das Testen dieser Composables
erschweren und
Vorschauenunterbrechen kann. Übergeben Sie stattdessen nur die Daten und Funktionen, die sie als Parameter benötigen.
Sie können ViewModel-Instanzen verwenden, um den Status für Composables auf Unterbildschirmebene zu verwalten. Beachten Sie jedoch den
ViewModel's
Lebenszyklus und Bereich. Wenn das
Composable in sich geschlossen ist, sollten Sie Hilt verwenden, um
das ViewModel einzufügen, damit Sie keine Abhängigkeiten von übergeordneten
Composables übergeben müssen.
Wenn Ihr ViewModel Abhängigkeiten hat, verwendet viewModel() optional
ViewModelProvider.Factory
als Parameter.
Weitere Informationen zu ViewModel in Compose und zur Verwendung von Instanzen
mit der Navigation Compose-Bibliothek oder Aktivitäten und Fragmenten
finden Sie in der Dokumentation zur Interoperabilität.
Datenstreams
Compose bietet Erweiterungen für die beliebtesten stream-basierten Lösungen von Android. Jede dieser Erweiterungen wird von einem anderen Artefakt bereitgestellt:
LiveData.observeAsState()ist im Artefaktandroidx.compose.runtime:runtime-livedata:$composeVersionenthalten.Flow.collectAsState()erfordert keine zusätzlichen Abhängigkeiten.Observable.subscribeAsState()ist im Artefaktandroidx.compose.runtime:runtime-rxjava2:$composeVersionoderandroidx.compose.runtime:runtime-rxjava3:$composeVersionenthalten.
Diese Artefakte werden als Listener registriert und stellen die Werte als ein
State dar. Immer wenn ein neuer Wert ausgegeben wird, führt Compose eine Neuzusammensetzung der UI-Teile durch, in denen state.value verwendet wird. In diesem Code wird beispielsweise ShowData jedes Mal neu zusammengesetzt, wenn
exampleLiveData einen neuen Wert ausgibt.
// 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) } }
Asynchrone Vorgänge in Compose
Mit Jetpack Compose können Sie asynchrone Vorgänge mit Coroutinen in Ihren Composables ausführen.
Navigation
Die Navigationskomponente bietet Unterstützung für Jetpack Compose-Anwendungen. Weitere Informationen finden Sie unter Mit Compose navigieren und Jetpack Navigation zu Navigation Compose migrieren.
Hilt
Hilt ist die empfohlene Lösung für die Abhängigkeitsinjektion in Android-Apps und funktioniert nahtlos mit Compose.
Die viewModel() im Abschnitt ViewModel erwähnte Funktion
verwendet automatisch das ViewModel, das Hilt mit der @HiltViewModel
Annotation erstellt. Wir haben eine Dokumentation mit Informationen zur ViewModel-Integration von Hilt bereitgestellt.
@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() ) { /* ... */ }
Hilt und Navigation
Hilt lässt sich auch in die Navigation Compose-Bibliothek einbinden. Fügen Sie Ihrer Gradle-Datei die folgenden zusätzlichen Abhängigkeiten hinzu:
Groovy
dependencies { implementation 'androidx.hilt:hilt-navigation-compose:1.3.0' }
Kotlin
dependencies { implementation("androidx.hilt:hilt-navigation-compose:1.3.0") }
Wenn Sie Navigation Compose verwenden, verwenden Sie immer die hiltViewModel Composable
Funktion, um eine Instanz Ihres @HiltViewModel annotierten ViewModel abzurufen.
Dies funktioniert mit Fragmenten oder Aktivitäten, die mit @AndroidEntryPoint annotiert sind.
Wenn ExampleScreen beispielsweise ein Ziel in einem Navigationsdiagramm ist, rufen Sie hiltViewModel() auf, um eine Instanz von ExampleViewModel abzurufen, die auf das Ziel beschränkt ist, wie im folgenden Code-Snippet gezeigt:
// 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) } /* ... */ } }
Wenn Sie stattdessen die Instanz eines ViewModel abrufen müssen, das auf
Navigationsrouten oder das
Navigationsdiagramm
beschränkt ist, verwenden Sie die Composable-Funktion hiltViewModel und übergeben Sie den entsprechenden
backStackEntry als Parameter:
// 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
Mit der Paging
Bibliothek
können Sie Daten schrittweise laden. Sie wird in Compose unterstützt.
Auf der Release-Seite von Paging
finden SieInformationen zur zusätzlichen Abhängigkeit paging-compose, die dem Projekt hinzugefügt werden muss
, und zur zugehörigen Version.
Hier sehen Sie ein Beispiel für die Compose-APIs der Paging-Bibliothek:
@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") } } }
Weitere Informationen zur Verwendung von Paging in Compose finden Sie in der Dokumentation zu Listen und Rastern.
Maps
Mit der Maps Compose Bibliothek können Sie Google Maps in Ihrer App bereitstellen. Hier ist ein Anwendungsbeispiel:
@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" ) } }
Empfehlungen für Sie
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist
- Nebeneffekte in Compose
- Status und Jetpack Compose
- UI-Status in Compose speichern