Możesz dodać interfejs oparty na Compose do istniejącej aplikacji, która korzysta z projektu opartego na widokach.
Aby utworzyć nowy ekran oparty w całości na Compose, wywołaj w aktywności metodę setContent()
i przekaż dowolne funkcje kompozycyjne.
class ExampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { // In here, we can call composables! MaterialTheme { Greeting(name = "compose") } } } } @Composable fun Greeting(name: String) { Text(text = "Hello $name!") }
Ten kod wygląda tak samo jak w aplikacji korzystającej tylko z Compose.
ViewCompositionStrategy
przez ComposeView
ViewCompositionStrategy
określa, kiedy należy usunąć kompozycję. Domyślna wartość, ViewCompositionStrategy.Default
, powoduje usunięcie obiektu Composition, gdy powiązany z nim obiekt ComposeView
zostanie odłączony od okna, chyba że jest częścią kontenera puli, takiego jak RecyclerView
. W aplikacji z jednym komponentem Activity, która korzysta tylko z Compose, to domyślne zachowanie jest pożądane. Jeśli jednak stopniowo dodajesz Compose do bazy kodu, w niektórych przypadkach może to powodować utratę stanu.
Aby zmienić ViewCompositionStrategy
, wywołaj metodę setViewCompositionStrategy()
i podaj inną strategię.
W tabeli poniżej znajdziesz podsumowanie różnych scenariuszy, w których możesz używać funkcji
ViewCompositionStrategy
:
ViewCompositionStrategy |
Opis i scenariusz interoperacyjności |
---|---|
DisposeOnDetachedFromWindow |
Kompozycja zostanie usunięta, gdy bazowy element ComposeView zostanie odłączony od okna. Został zastąpiony przez DisposeOnDetachedFromWindowOrReleasedFromPool .Scenariusz interoperacyjności: * ComposeView czy jest to jedyny element w hierarchii widoków, czy występuje w kontekście ekranu mieszanego (widok/Compose) (nie w fragmencie). |
DisposeOnDetachedFromWindowOrReleasedFromPool (domyślna) |
Podobnie jak w przypadku DisposeOnDetachedFromWindow , gdy kompozycja nie znajduje się w kontenerze puli, np. w RecyclerView . Jeśli znajduje się w kontenerze puli, zostanie usunięty, gdy kontener puli zostanie odłączony od okna lub gdy element zostanie odrzucony (czyli gdy pula będzie pełna).Scenariusz interoperacyjności: * ComposeView czy jest to jedyny element w hierarchii widoków, czy znajduje się w kontekście ekranu mieszanego (widok/Compose) (nie w fragmencie).* ComposeView jako element w kontenerze puli, np. RecyclerView . |
DisposeOnLifecycleDestroyed |
Kompozycja zostanie usunięta, gdy podany element Lifecycle zostanie zniszczony.Scenariusz interoperacyjności * ComposeView w widoku fragmentu. |
DisposeOnViewTreeLifecycleDestroyed |
Kompozycja zostanie usunięta, gdy Lifecycle należący do LifecycleOwner zwróconego przez ViewTreeLifecycleOwner.get następnego okna, do którego dołączony jest widok, zostanie zniszczony.Scenariusz interoperacyjny: * ComposeView w widoku fragmentu.* ComposeView w obiekcie View, w którym cykl życia nie jest jeszcze znany. |
ComposeView
w sekcji Fragmenty
Jeśli chcesz włączyć treści interfejsu Compose w fragmencie lub istniejącym układzie View, użyj ComposeView
i wywołaj jego metodę setContent()
. ComposeView
to Android View
.
Element ComposeView
możesz umieścić w układzie XML tak samo jak każdy inny element View
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
W kodzie źródłowym Kotlin rozwiń układ z zasobu układu zdefiniowanego w XML. Następnie pobierz
ComposeView
za pomocą identyfikatora XML, ustaw strategię kompozycji, która najlepiej pasuje do hosta View
, i wywołaj setContent()
, aby użyć funkcji Compose.
class ExampleFragmentXml : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { val view = inflater.inflate(R.layout.fragment_example, container, false) val composeView = view.findViewById<ComposeView>(R.id.compose_view) composeView.apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { // In Compose world MaterialTheme { Text("Hello Compose!") } } } return view } }
Możesz też użyć powiązania widoku, aby uzyskać odwołania do ComposeView
, odwołując się do wygenerowanej klasy powiązania dla pliku układu XML:
class ExampleFragment : Fragment() { private var _binding: FragmentExampleBinding? = null // This property is only valid between onCreateView and onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentExampleBinding.inflate(inflater, container, false) val view = binding.root binding.composeView.apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { // In Compose world MaterialTheme { Text("Hello Compose!") } } } return view } override fun onDestroyView() { super.onDestroyView() _binding = null } }
Rysunek 1. Wyświetla dane wyjściowe kodu, który dodaje elementy Compose w hierarchii interfejsu View. Tekst „Hello Android!” jest wyświetlany przez widżet TextView
. Tekst „Hello Compose!” jest wyświetlany przez element tekstowy Compose.
Możesz też umieścić ComposeView
bezpośrednio we fragmencie, jeśli pełny ekran jest zbudowany za pomocą Compose, co pozwala całkowicie uniknąć używania pliku układu XML.
class ExampleFragmentNoXml : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { // Dispose of the Composition when the view's LifecycleOwner // is destroyed setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) setContent { MaterialTheme { // In Compose world Text("Hello Compose!") } } } } }
Wiele instancji ComposeView
w tym samym układzie
Jeśli w tym samym układzie występuje kilka elementów ComposeView
, każdy z nich musi mieć unikalny identyfikator, aby element savedInstanceState
działał prawidłowo.
class ExampleFragmentMultipleComposeView : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View = LinearLayout(requireContext()).apply { addView( ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed ) id = R.id.compose_view_x // ... } ) addView(TextView(requireContext())) addView( ComposeView(requireContext()).apply { setViewCompositionStrategy( ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed ) id = R.id.compose_view_y // ... } ) } }
Identyfikatory ComposeView
są zdefiniowane w pliku res/values/ids.xml
:
<resources> <item name="compose_view_x" type="id" /> <item name="compose_view_y" type="id" /> </resources>
Wyświetlanie podglądu komponentów w Edytorze układu
Komponenty możesz też wyświetlać w Edytorze układu w przypadku układu XML zawierającego element ComposeView
. Dzięki temu możesz zobaczyć, jak komponenty kompozycyjne wyglądają w układzie mieszanym, który zawiera widoki i kompozycje.
Załóżmy, że chcesz wyświetlić w Edytorze układu ten komponent: Uwaga: funkcje kompozycyjne oznaczone adnotacją @Preview
są dobrymi kandydatami do podglądu w edytorze układu.
@Preview @Composable fun GreetingPreview() { Greeting(name = "Android") }
Aby wyświetlić ten komponent, użyj atrybutu tools:composableName
tools i ustaw jego wartość na w pełni kwalifikowaną nazwę komponentu, który ma być wyświetlany w układzie.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.compose.ui.platform.ComposeView android:id="@+id/my_compose_view" tools:composableName="com.example.compose.snippets.interop.InteroperabilityAPIsSnippetsKt.GreetingPreview" android:layout_height="match_parent" android:layout_width="match_parent"/> </LinearLayout>
Dalsze kroki
Teraz, gdy znasz już interfejsy API interoperacyjności, które umożliwiają używanie Compose w widokach, dowiedz się, jak używać widoków w Compose.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony.
- Inne kwestie, które warto wziąć pod uwagę
- Strategia migracji {:#migration-strategy}
- Porównywanie skuteczności funkcji Tworzenie i Wyświetlanie