In „Compose“ können Sie Ihre bevorzugten Bibliotheken verwenden. In diesem Abschnitt wird beschrieben, wie Sie einige der nützlichsten Bibliotheken einbinden.
Aktivitäten
Wenn Sie „Compose“ in einer Aktivität verwenden möchten, müssen Sie ComponentActivity
verwenden. Dies ist eine abgeleitete Klasse von Activity
, die die entsprechenden LifecycleOwner
und Komponenten für Compose bereitstellt. Außerdem bietet es zusätzliche APIs, die Ihren Code vom Überschreiben von Methoden in Ihrer Aktivitätsklasse entkoppeln.
Mit der Funktion Activity Compose lassen sich diese APIs zusammensetzbaren Funktionen zur Verfügung stellen, sodass das Überschreiben von Methoden außerhalb der zusammensetzbaren Funktionen oder das Abrufen einer expliziten Activity
-Instanz nicht mehr erforderlich ist.
Darüber hinaus sorgen diese APIs dafür, dass sie nur einmal initialisiert werden, die Neuzusammensetzung überdauern und ordnungsgemäß bereinigt werden, wenn die zusammensetzbare Funktion aus der Zusammensetzung entfernt wird.
Aktivitätsergebnis
Mit der rememberLauncherForActivityResult()
API können Sie ein Ergebnis aus einer Aktivität in Ihrer zusammensetzbaren Funktion abrufen:
@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" ) } }
Dieses Beispiel zeigt einen einfachen GetContent()
-Vertrag. Durch Tippen auf die Schaltfläche wird die Anfrage gestartet. Das nachgestellte Lambda für rememberLauncherForActivityResult()
wird aufgerufen, sobald der Nutzer ein Bild ausgewählt hat und zur Startaktivitä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 mit dieser Technik Inhalte aus dem Framework und in anderen gängigen Mustern anfordern können. Sie können auch Ihre eigenen benutzerdefinierten Verträge erstellen und mit dieser Technik verwenden.
Laufzeitberechtigungen anfordern
Die oben erläuterte Activity Result API und der oben beschriebene rememberLauncherForActivityResult()
können verwendet werden, um Laufzeitberechtigungen anzufordern. Dabei werden der RequestPermission
-Vertrag für eine einzelne Berechtigung oder der Vertrag RequestMultiplePermissions
für mehrere Berechtigungen verwendet.
Mit der Accompanist-Berechtigungsbibliothek lässt sich auch eine Ebene über diesen APIs erstellen, um den aktuell erteilten Status für Berechtigungen dem Status zuzuordnen, den Ihre Compose-UI verwenden kann.
Umgang mit der Zurück-Schaltfläche des Systems
Wenn Sie eine benutzerdefinierte Zurück-Navigation bereitstellen und das Standardverhalten der Zurück-Schaltfläche des Systems in der zusammensetzbaren Funktion überschreiben möchten, kann die zusammensetzbare Funktion eine BackHandler
verwenden, um dieses Ereignis abzufangen:
var backHandlingEnabled by remember { mutableStateOf(true) } BackHandler(backHandlingEnabled) { // Handle back press }
Das erste Argument steuert, ob BackHandler
derzeit aktiviert ist. Mit diesem Argument können Sie den Handler je nach Status der Komponente vorübergehend deaktivieren. Die nachgestellte Lambda-Funktion wird aufgerufen, wenn der Nutzer ein Systemback-Ereignis auslöst und BackHandler
derzeit aktiviert ist.
ViewModel
Wenn Sie die ViewModel-Bibliothek für Architekturkomponenten verwenden, können Sie über jede zusammensetzbare Funktion auf ein ViewModel
zugreifen, indem Sie die Funktion viewModel()
aufrufen. Fügen Sie Ihrer Gradle-Datei die folgende Abhängigkeit hinzu:
Cool
dependencies { implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1' }
Kotlin
dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1") }
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 wird die zurückgegebene ViewModel
auf die einschließende Aktivität, das Fragment oder das Navigationsziel beschränkt und so lange beibehalten, wie der Bereich aktiv ist.
Wenn die zusammensetzbare Funktion beispielsweise in einer Aktivität verwendet wird, gibt viewModel()
dieselbe Instanz zurück, bis die Aktivität abgeschlossen 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
Normalerweise greifen Sie auf ViewModel
-Instanzen auf zusammensetzbaren Funktionen auf Bildschirmebene zu, d. h. in der Nähe einer zusammensetzbaren Stammfunktion, die von einer Aktivität, einem Fragment oder einem Ziel eines Navigationsdiagramms aufgerufen wird. Das liegt daran, dass ViewModel
s standardmäßig auf diese Objekte auf Bildschirmebene ausgerichtet sind. Hier finden Sie weitere Informationen zum Lebenszyklus und Bereich einer ViewModel
.
Vermeiden Sie es, ViewModel
-Instanzen an andere zusammensetzbare Funktionen zu übergeben, da dies das Testen dieser zusammensetzbaren Funktionen erschweren und die Vorschau beeinträchtigen kann. Stattdessen sollten Sie nur die Daten und Funktionen,
die sie benötigen, als Parameter übergeben.
Sie können ViewModel
-Instanzen verwenden, um den Status für zusammensetzbare Funktionen auf untergeordneten Bildschirmebene zu verwalten. Beachten Sie jedoch den Lebenszyklus und Bereich von ViewModel
. Wenn die zusammensetzbare Funktion in sich abgeschlossen ist, können Sie das ViewModel
mithilfe von Hilt einfügen. So vermeiden Sie, dass Abhängigkeiten von übergeordneten zusammensetzbaren Funktionen übergeben werden müssen.
Wenn ViewModel
Abhängigkeiten enthält, verwendet viewModel()
einen optionalen ViewModelProvider.Factory
als Parameter.
Weitere Informationen zu ViewModel
in Compose und zur Verwendung von Instanzen mit der Navigation Compose-Bibliothek oder zu Aktivitäten und Fragmenten finden Sie in der Interoperabilitätsdokumentation.
Datenstreams
Compose enthält Erweiterungen für die beliebtesten streambasierten Android-Lösungen. Jede dieser Erweiterungen wird von einem anderen Artefakt bereitgestellt:
LiveData.observeAsState()
ist im Artefaktandroidx.compose.runtime:runtime-livedata:$composeVersion
enthalten.Flow.collectAsState()
erfordert keine zusätzlichen Abhängigkeiten.Observable.subscribeAsState()
ist im Artefaktandroidx.compose.runtime:runtime-rxjava2:$composeVersion
oderandroidx.compose.runtime:runtime-rxjava3:$composeVersion
enthalten.
Diese Artefakte werden als Listener registriert und stellen die Werte als State
dar. Immer wenn ein neuer Wert ausgegeben wird, setzt „Compose“ die Teile der UI neu zusammen, in denen state.value
verwendet wird. In diesem Code wird ShowData
beispielsweise 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 Koroutinen in Ihren zusammensetzbaren Funktionen ausführen.
Weitere Informationen findest du in den APIs für LaunchedEffect
, produceState
und rememberCoroutineScope
in der Dokumentation zu Nebeneffekten.
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.
Griff
Hilt ist die empfohlene Lösung für das Einschleusen von Abhängigkeiten in Android-Apps und funktioniert nahtlos mit Compose.
Die im Abschnitt ViewModel erwähnte Funktion viewModel()
verwendet automatisch die ViewModel-Funktion, die von Hilt mit der Annotation @HiltViewModel
erstellt wird. In der Dokumentation findest du Informationen zur ViewModel-Integration von 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() ) { /* ... */ }
Griff und Navigation
Hilt ist auch in die Navigation Compose-Bibliothek integriert. Fügen Sie Ihrer Gradle-Datei die folgenden zusätzlichen Abhängigkeiten hinzu:
Cool
dependencies { implementation 'androidx.hilt:hilt-navigation-compose:1.0.0' }
Kotlin
dependencies { implementation("androidx.hilt:hilt-navigation-compose:1.0.0") }
Wenn Sie „Navigation Compose“ verwenden, verwenden Sie immer die zusammensetzbare Funktion hiltViewModel
, um eine Instanz Ihrer mit @HiltViewModel
annotierten ViewModel
abzurufen.
Dies funktioniert mit Fragmenten oder Aktivitäten, die mit @AndroidEntryPoint
annotiert sind.
Wenn ExampleScreen
beispielsweise ein Ziel in einer Navigationsgrafik 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öchten, der auf Navigationsrouten oder die Navigationsgrafik beschränkt ist, verwenden Sie die zusammensetzbare 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
Die Paging-Bibliothek erleichtert das schrittweise Laden von Daten und wird in Compose unterstützt.
Die Releaseseite "Paging" enthält Informationen zur zusätzlichen paging-compose
-Abhängigkeit, die dem Projekt und seiner Version hinzugefügt werden muss.
Hier 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 des Seitenumbruchs in „Compose“ finden Sie in der Dokumentation zu Listen und Rastern.
Maps
Sie können die Bibliothek Maps Compose verwenden, um Google Maps in Ihrer App bereitzustellen. Hier 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 = MarkerState(position = singapore), title = "Singapore", snippet = "Marker in Singapore" ) } }
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Nebeneffekte in der Funktion „Schreiben“
- State und Jetpack Compose
- UI-Status in „Compose“ speichern