W interfejsie tworzenia możesz uwzględnić hierarchię widoku Androida. Ta metoda jest szczególnie przydatna, gdy chcesz skorzystać z elementów interfejsu, które nie są jeszcze dostępne w funkcji tworzenia wiadomości, np. AdView
.
Takie podejście umożliwia również ponowne wykorzystanie utworzonych wcześniej widoków niestandardowych.
Aby dołączyć element widoku danych lub hierarchię, użyj funkcji kompozycyjnej AndroidView
. Funkcja AndroidView
przekazuje lambda, która zwraca wartość View
. AndroidView
udostępnia też wywołanie zwrotne update
, które jest wywoływane, gdy widok jest powiększony. AndroidView
tworzy się ponownie za każdym razem, gdy zmieni się odczyt State
w wywołaniu zwrotnym. AndroidView
, podobnie jak wiele innych wbudowanych funkcji kompozycyjnych, przyjmuje parametr Modifier
, którego można użyć na przykład do ustawienia pozycji w nadrzędnym elemencie kompozycyjnym.
@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
z powiązaniem widoku
Aby umieścić układ XML, użyj interfejsu API AndroidViewBinding
udostępnianego przez bibliotekę androidx.compose.ui:ui-viewbinding
. Aby to zrobić, musisz włączyć w projekcie powiązanie widoku danych.
@Composable fun AndroidViewBindingExample() { AndroidViewBinding(ExampleLayoutBinding::inflate) { exampleView.setBackgroundColor(Color.GRAY) } }
AndroidView
na leniwszych listach
Jeśli używasz elementu AndroidView
na liście Leniwo (LazyColumn
, LazyRow
, Pager
itp.), rozważ zastosowanie przeciążenia AndroidView
wprowadzonego w wersji 1.4.0-rc01. To przeciążenie umożliwia ponowne wykorzystanie bazowej instancji View
w przypadku ponownego użycia kompozycji, w której występuje kompozycja (tak jak w przypadku leniwych list).
Przeciążenie obiektu AndroidView
powoduje dodanie 2 dodatkowych parametrów:
onReset
– wywołanie zwrotne w celu zasygnalizowania, żeView
zostanie ponownie użyty. To pole nie może mieć wartości null, aby umożliwić ponowne używanie widoków.onRelease
(opcjonalnie) – wywołanie zwrotne w celu zasygnalizowania, że komponentView
zakończył kompozycję i nie jest ponownie używany.
@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() } ) } } }
Fragmenty w oknie tworzenia
Użyj funkcji AndroidViewBinding
kompozycyjnej, aby dodać element Fragment
w sekcji Utwórz.
Funkcja AndroidViewBinding
obsługuje fragmenty z obsługą fragmentów, na przykład usuwa fragment, gdy funkcja kompozycyjna opuści kompozycję.
Aby to zrobić, dodaj kod XML zawierający FragmentContainerView
jako właściciela Twojego elementu Fragment
.
Jeśli na przykład zdefiniowano my_fragment_layout.xml
, możesz użyć poniższego kodu, zastępując atrybut XML android:name
nazwą klasy 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" />
Rozszerz ten fragment w oknie Utwórz w następujący sposób:
@Composable fun FragmentInComposeExample() { AndroidViewBinding(MyFragmentLayoutBinding::inflate) { val myFragment = fragmentContainerView.getFragment<MyFragment>() // ... } }
Jeśli musisz użyć wielu fragmentów w tym samym układzie, upewnij się, że każdy element FragmentContainerView
ma unikalny identyfikator.
Wywoływanie platformy Android z poziomu Compose
Tworzenie działa w ramach klas platformy Androida. Na przykład jest hostowane w klasach Android View, takich jak Activity
czy Fragment
, i może korzystać z klas platformy Androida, takich jak Context
, zasoby systemowe, Service
czy BroadcastReceiver
.
Więcej informacji o zasobach systemowych znajdziesz w artykule Zasoby w oknie tworzenia wiadomości.
Lokalna kompozycja
Klasy CompositionLocal
umożliwiają pośrednie przekazywanie danych za pomocą funkcji kompozycyjnych. Zwykle mają one wartość w określonym węźle drzewa interfejsu. Jej elementy podrzędne mogą być używane przez kompozycyjne elementy podrzędne bez deklarowania CompositionLocal
jako parametru funkcji kompozycyjnej.
CompositionLocal
służy do propagowania wartości typów platform Androida w sekcji Utwórz, takich jak Context
, Configuration
czy View
, gdzie kod tworzenia wiadomości jest hostowany z odpowiednimi parametrami LocalContext
, LocalConfiguration
i LocalView
.
Pamiętaj, że klasy CompositionLocal
mają prefiks Local
, co ułatwia wykrywanie dzięki autouzupełnianiu w IDE.
Aby uzyskać dostęp do bieżącej wartości elementu CompositionLocal
, użyj jego właściwości current
. Na przykład poniższy kod wyświetla toast, podając parametr LocalContext.current
w metodzie Toast.makeToast
.
@Composable fun ToastGreetingButton(greeting: String) { val context = LocalContext.current Button(onClick = { Toast.makeText(context, greeting, Toast.LENGTH_SHORT).show() }) { Text("Greet") } }
Pełniejszy przykład znajdziesz w sekcji Studium przypadku: BroadcastReceivedrs na końcu tego dokumentu.
Inne interakcje
Jeśli nie ma zdefiniowanego narzędzia do danej interakcji, sprawdzoną metodą jest stosowanie się do ogólnych wytycznych dotyczących tworzenia wiadomości, przepływu danych w dół, w górę zdarzeń (więcej szczegółów na ten temat znajdziesz w sekcji Myślenie tworzenia wiadomości). Na przykład ten element kompozycyjny uruchamia inną aktywność:
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) } }
Studium przypadku: odbiorniki
Aby uzyskać bardziej realistyczny przykład funkcji, które warto przenieść lub zaimplementować w tworzeniu, oraz zaprezentować CompositionLocal
i efekty uboczne, załóżmy, że BroadcastReceiver
trzeba zarejestrować za pomocą funkcji kompozycyjnej.
Rozwiązanie wykorzystuje uprawnienia LocalContext
do wykorzystania bieżącego kontekstu oraz efekty uboczne rememberUpdatedState
i 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 */ }
Dalsze kroki
Teraz, gdy znasz już interfejsy API interoperacyjności podczas korzystania z tworzenia w widokach i odwrotnie, zapoznaj się ze stroną Inne uwagi, aby dowiedzieć się więcej.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony
- Inne uwagi
- Efekty uboczne w oknie tworzenia wiadomości
- Dane o zakresie lokalnym w CompositionLocal