Możesz dodać interfejs użytkownika oparty na Compose do istniejącej aplikacji, która korzysta z projektu opartego na widoku.
Aby utworzyć nowy ekran oparty całkowicie na Compose, wywołaj w swojej czynności metodę setContent()
i przekaż dowolne funkcje kompozytowe.
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 kod w aplikacji tylko do tworzenia wiadomości.
ViewCompositionStrategy
przez ComposeView
ViewCompositionStrategy
określa, kiedy kompozycja powinna zostać usunięta. Domyślna wartość,
ViewCompositionStrategy.Default
,
usuwa kompozycję, gdy element podstawowy
ComposeView
odłącza się od okna, chyba że jest częścią kontenera z grupowaniem, takiego jak
RecyclerView
. W przypadku aplikacji z jedną aktywnością, która korzysta tylko z Compose, takie domyślne zachowanie jest pożądane, ale jeśli stopniowo dodajesz Compose do repozytorium kodu, w niektórych przypadkach może to spowodować utratę stanu.
Aby zmienić ViewCompositionStrategy
, wywołaj metodę setViewCompositionStrategy()
i podaj inną strategię.
Tabela poniżej zawiera podsumowanie różnych scenariuszy, w których możesz użyć funkcjiViewCompositionStrategy
:
ViewCompositionStrategy |
Opis i scenariusz interoperacyjności |
---|---|
DisposeOnDetachedFromWindow |
Skład zostanie usunięty, gdy podstawowy element ComposeView zostanie odłączony od okna. Został zastąpiony przez DisposeOnDetachedFromWindowOrReleasedFromPool .Scenariusz interoperacyjności: * ComposeView czy jest to jedyny element w hierarchii widoku czy w kontekście mieszanego ekranu Widok/Kompozycja (nie w Fragment). |
DisposeOnDetachedFromWindowOrReleasedFromPool (wartość domyślna) |
Podobnie jak w przypadku DisposeOnDetachedFromWindow , gdy kompozycja nie znajduje się w kontenerze z poolingiem, np. RecyclerView . Jeśli znajduje się w kontenerze z poolingiem, zostanie usunięty, gdy sam kontener z poolingiem zostanie odłączony od okna lub gdy element zostanie odrzucony (czyli gdy pula jest pełna).Scenariusz interoperacyjności: * ComposeView niezależnie od tego, czy jest jedynym elementem w hierarchii widoku, czy w kontekście mieszanego ekranu widoku/tworzenia (nie w Fragment).* ComposeView jako element w kontenerze zbiorczym, takim jak RecyclerView . |
DisposeOnLifecycleDestroyed |
Skład zostanie usunięty, gdy podany obiekt Lifecycle zostanie usunięty.Scenariusz interoperacyjności * ComposeView w widoku fragmentu. |
DisposeOnViewTreeLifecycleDestroyed |
Skład zostanie usunięty, gdy Lifecycle należący do LifecycleOwner zwracany przez ViewTreeLifecycleOwner.get następnego okna, do którego jest przyłączony widok, zostanie usunięty.Scenariusz interoperacyjności: * ComposeView w widoku fragmentu.* ComposeView w widoku, w którym cykl życia nie jest jeszcze znany. |
ComposeView
w Fragmentach
Jeśli chcesz uwzględnić zawartość interfejsu Compose w fragmentie lub istniejącym widoku, użyj klasy ComposeView
i wywołaj jej metodę setContent()
. ComposeView
to urządzenie z Androidem View
.
Możesz umieścić element ComposeView
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 źródłowym kodzie Kotlina napełnij układ z zasobu układu zdefiniowanego w pliku XML. Następnie pobierz ComposeView
za pomocą identyfikatora XML, ustaw strategię tworzenia, która najlepiej pasuje do hosta View
, i wywołaj setContent()
, aby użyć 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ć widoku z powiązaniem, aby uzyskać odwołania do elementu ComposeView
, odwołując się do wygenerowanej klasy powiązania w 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. Pokazuje to wynik działania kodu, który dodaje elementy Compose w hierarchii interfejsu View. Tekst „Hello Android!” wyświetla się w widżecie TextView
. Tekst „Cześć, Compose” jest wyświetlany przez element tekstowy Compose.
Możesz też umieścić ComposeView
bezpośrednio w fragmentach, jeśli Twój pełny ekran został utworzony za pomocą Compose. Pozwoli Ci to 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 wystąpień ComposeView
w tym samym układzie
Jeśli w tym samym układzie jest 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 elementów składanych w Edytorze układu
Możesz też wyświetlić podgląd komponentów w Edytorze układu dla układu XML zawierającego ComposeView
. Dzięki temu możesz zobaczyć, jak Twoje komponenty wyglądają w układzie mieszanym widoków i edytora.
Załóżmy, że chcesz wyświetlić w Edytorze układu tę kompozycję. Pamiętaj, że elementy składane oznaczone etykietą @Preview
nadają się do wyświetlania podglądu w Edytorze układu.
@Preview @Composable fun GreetingPreview() { Greeting(name = "Android") }
Aby wyświetlić tę kompozycję, użyj atrybutu tools:composableName
tools i ustaw jego wartość na pełną nazwę skompilowanej kompozycji, aby wyświetlić jej podgląd 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 interfejsy API interoperacyjności, które umożliwiają korzystanie z Compose w widoku, dowiedz się, jak używać widoku w Compose.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy obsługa JavaScript jest wyłączona
- Inne kwestie
- Strategia migracji {:#migration-strategy}
- Porównywanie skuteczności funkcji tworzenia wiadomości i wyświetlania