Sie können eine Android View-Hierarchie in eine Compose-UI einbinden. Dieser Ansatz ist
besonders nützlich, wenn Sie UI-Elemente verwenden möchten, die in
Schreiben, Gefällt mir
AdView
Auf diese Weise können Sie auch benutzerdefinierte Ansichten wiederverwenden, die Sie erstellt haben.
Um ein Ansichtselement oder eine Hierarchie hinzuzufügen, verwenden Sie die AndroidView
zusammensetzbar. AndroidView
wird eine Lambda-Funktion übergeben, die ein
View
AndroidView
bietet auch eine update
-Callback, der aufgerufen wird, wenn sich die Ansicht erhöht. AndroidView
wird neu zusammengesetzt.
wenn sich ein State
-Lesevorgang innerhalb des Callbacks ändert. AndroidView
, wie viele
anderen integrierten zusammensetzbaren Funktionen, verwendet einen Modifier
-Parameter, der verwendet werden kann,
um seine Position in der übergeordneten zusammensetzbaren Funktion festzulegen.
@Composable fun CustomView() { var selectedItem by remember { mutableStateOf(0) } // Adds view to Compose AndroidView( modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree factory = { context -> // Creates view MyView(context).apply { // Sets up listeners for View -> Compose communication setOnClickListener { selectedItem = 1 } } }, update = { view -> // View's been inflated or state read in this block has been updated // Add logic here if necessary // As selectedItem is read here, AndroidView will recompose // whenever the state changes // Example of Compose -> View communication view.selectedItem = selectedItem } ) } @Composable fun ContentExample() { Column(Modifier.fillMaxSize()) { Text("Look at this CustomView!") CustomView() } }
AndroidView
mit Bindung der Ansicht
Verwenden Sie zum Einbetten eines XML-Layouts die Methode
AndroidViewBinding
API, die von der androidx.compose.ui:ui-viewbinding
-Bibliothek bereitgestellt wird. Bis
Wenn Sie dies tun möchten, muss in Ihrem Projekt die Bindung zum Ansehen aktiviert sein.
@Composable fun AndroidViewBindingExample() { AndroidViewBinding(ExampleLayoutBinding::inflate) { exampleView.setBackgroundColor(Color.GRAY) } }
AndroidView
in Lazy-Listen
Wenn Sie ein AndroidView
in einer Lazy-Liste verwenden (LazyColumn
, LazyRow
,
Pager
usw.), sollten Sie die Verwendung von AndroidView
in Betracht ziehen.
in Version 1.4.0-rc01 eingeführt. Aufgrund dieser Überlastung kann Compose
Die zugrunde liegende View
-Instanz, wenn die enthaltende Zusammensetzung unverändert wiederverwendet wird
was bei Lazy Listen der Fall ist.
Diese Überlastung von AndroidView
fügt zwei zusätzliche Parameter hinzu:
onReset
– ein Callback, der ausgelöst wird, um zu signalisieren, dass dasView
gleich beginnt. wiederverwendet werden. Der Wert darf nicht null sein, damit Ansichten wiederverwendet werden können.onRelease
(optional): Ein Callback, der aufgerufen wird, um zu signalisieren, dass dasView
hat die Zusammensetzung verlassen und wird nicht erneut verwendet.
@OptIn(ExperimentalComposeUiApi::class) @Composable fun AndroidViewInLazyList() { LazyColumn { items(100) { index -> AndroidView( modifier = Modifier.fillMaxSize(), // Occupy the max size in the Compose UI tree factory = { context -> MyView(context) }, update = { view -> view.selectedItem = index }, onReset = { view -> view.clear() } ) } } }
Fragmente in Compose
Mit der zusammensetzbaren Funktion AndroidViewBinding
können Sie in „Schreiben“ ein Fragment
einfügen.
Bei AndroidViewBinding
erfolgt eine fragmentierte Verarbeitung, wie z. B. das Entfernen des
Fragment zurück, wenn die zusammensetzbare Funktion die Komposition verlässt.
Dazu bläst du eine XML-Datei auf, die FragmentContainerView
enthält.
als Inhaber von Fragment
.
Wenn Sie beispielsweise my_fragment_layout.xml
definiert haben, können Sie Folgendes verwenden:
Code wie diesen aussehen und dabei das XML-Attribut android:name
durch Ihre
Klassenname von Fragment
:
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container_view" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.example.compose.snippets.interop.MyFragment" />
Blenden Sie dieses Fragment in Compose wie folgt auf:
@Composable fun FragmentInComposeExample() { AndroidViewBinding(MyFragmentLayoutBinding::inflate) { val myFragment = fragmentContainerView.getFragment<MyFragment>() // ... } }
Wenn Sie mehrere Fragmente im selben Layout verwenden müssen,
eindeutige ID für jede FragmentContainerView
definiert.
Android-Framework aus Compose aufrufen
Compose wird in den Android-Framework-Klassen ausgeführt. Zum Beispiel werden sie
auf Android View-Klassen wie Activity
oder Fragment
und verwenden möglicherweise Android
Framework-Klassen wie Context
, Systemressourcen,
Service
oder BroadcastReceiver
.
Weitere Informationen zu Systemressourcen finden Sie unter Ressourcen in Compose.
Zusammensetzung von Ortsansässigen
CompositionLocal
-Klassen ermöglichen die implizite Weitergabe von Daten über zusammensetzbare Funktionen. Sie sind
in der Regel mit einem Wert in einem bestimmten Knoten des UI-Baums bereitgestellt. Dieser Wert kann
von seinen zusammensetzbaren Nachfolgern verwendet werden, ohne das CompositionLocal
-Element zu deklarieren
als Parameter in der zusammensetzbaren Funktion verwenden.
Mit CompositionLocal
werden Werte für Android-Framework-Typen weitergegeben in
Verfassen, z. B. Context
, Configuration
oder die View
, in der das Feld „Schreiben“
mit der entsprechenden URL gehostet wird,
LocalContext
,
LocalConfiguration
oder
LocalView
.
Beachten Sie, dass CompositionLocal
-Klassen zur besseren Verbesserung das Präfix Local
vorangestellt ist.
mit der automatischen Vervollständigung in der IDE.
Greifen Sie über dessen current
auf den aktuellen Wert eines CompositionLocal
zu.
Property. Der folgende Code zeigt beispielsweise eine Toast-Nachricht an, indem
LocalContext.current
in die Toast.makeToast
-Methode ein.
@Composable fun ToastGreetingButton(greeting: String) { val context = LocalContext.current Button(onClick = { Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show() }) { Text("Greet") } }
Ein vollständigeres Beispiel finden Sie in der Fallstudie: BroadcastReceivers am Ende dieses Dokument.
Andere Interaktionen
Wenn für die gewünschte Interaktion kein Dienstprogramm definiert ist, sich an die allgemeinen Richtlinien für das Schreiben, Daten fließen nach unten, Ereignisse fließen nach oben (ausführlicher im Modul Denken in „Schreiben“). Diese zusammensetzbare Funktion startet eine andere Aktivität:
class OtherInteractionsActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // get data from savedInstanceState setContent { MaterialTheme { ExampleComposable(data, onButtonClick = { startActivity(Intent(this, MyActivity::class.java)) }) } } } } @Composable fun ExampleComposable(data: DataExample, onButtonClick: () -> Unit) { Button(onClick = onButtonClick) { Text(data.title) } }
Fallstudie: Rundfunkempfänger
Ein realistischeres Beispiel für Funktionen, die Sie migrieren oder implementieren möchten
in „Schreiben“ aktiviert, und um CompositionLocal
und
Effekte, nehmen wir an,
BroadcastReceiver
muss registriert werden über
eine zusammensetzbare Funktion.
Die Lösung nutzt LocalContext
, um den aktuellen Kontext zu verwenden, und
Nebenwirkungen von rememberUpdatedState
und DisposableEffect
.
@Composable fun SystemBroadcastReceiver( systemAction: String, onSystemEvent: (intent: Intent?) -> Unit ) { // Grab the current context in this part of the UI tree val context = LocalContext.current // Safely use the latest onSystemEvent lambda passed to the function val currentOnSystemEvent by rememberUpdatedState(onSystemEvent) // If either context or systemAction changes, unregister and register again DisposableEffect(context, systemAction) { val intentFilter = IntentFilter(systemAction) val broadcast = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { currentOnSystemEvent(intent) } } context.registerReceiver(broadcast, intentFilter) // When the effect leaves the Composition, remove the callback onDispose { context.unregisterReceiver(broadcast) } } } @Composable fun HomeScreen() { SystemBroadcastReceiver(Intent.ACTION_BATTERY_CHANGED) { batteryStatus -> val isCharging = /* Get from batteryStatus ... */ true /* Do something if the device is charging */ } /* Rest of the HomeScreen */ }
Nächste Schritte
Jetzt kennen Sie die APIs für die Interoperabilität bei der Verwendung der Funktion „Schreiben“ in Views und umgekehrt. finden Sie auf der Seite Weitere Überlegungen.
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Weitere Hinweise
- Nebeneffekte in der Funktion „Schreiben“
- Daten auf lokaler Ebene mit CompositionLocal