Puoi aggiungere una UI basata su Compose a un'app esistente che utilizza un design basato sulle visualizzazioni.
Per creare una nuova schermata interamente basata sulla scrittura, fai in modo che l'attività chiami il metodo setContent()
e trasmetti le funzioni componibili che preferisci.
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!") }
Questo codice è esattamente simile a quello che puoi trovare in un'app solo per Compose.
ViewCompositionStrategy
per ComposeView
ViewCompositionStrategy
definisce quando la composizione deve essere smaltita. L'impostazione predefinita, ViewCompositionStrategy.Default
, elimina la composizione quando l'elemento ComposeView
sottostante si scollega dalla finestra, a meno che non faccia parte di un container di pooling come un RecyclerView
. Questo comportamento predefinito è quello desiderato in un'app solo per Scrittura di attività. Tuttavia, se aggiungi in modo incrementale Compose al tuo codebase, questo comportamento potrebbe causare la perdita di stato in alcuni scenari.
Per modificare ViewCompositionStrategy
, chiama il metodo setViewCompositionStrategy()
e fornisci una strategia diversa.
La tabella seguente riassume i diversi scenari in cui puoi utilizzare ViewCompositionStrategy
:
ViewCompositionStrategy |
Descrizione e scenario di interoperabilità |
---|---|
DisposeOnDetachedFromWindow |
La composizione verrà eliminata quando l'elemento ComposeView sottostante verrà scollegato dalla finestra. È stato poi sostituito da DisposeOnDetachedFromWindowOrReleasedFromPool .Scenario di interazione: * ComposeView se è l'unico elemento nella gerarchia delle viste o nel contesto di una schermata mista di tipo Vista/Scrittura (non in Fragment). |
DisposeOnDetachedFromWindowOrReleasedFromPool (valore predefinito) |
Simile a DisposeOnDetachedFromWindow , quando la composizione non si trova in un contenitore di pooling, ad esempio un RecyclerView . Se si trova in un container di pool, viene eliminato quando il container stesso si scollega dalla finestra o quando l'elemento viene eliminato (ad esempio quando il pool è pieno).Scenario di interazione: * ComposeView se si tratta dell'unico elemento nella gerarchia di visualizzazione o nel contesto di una schermata mista di visualizzazione/scrittura (non in un frammento).* ComposeView come elemento in un container di pool come RecyclerView . |
DisposeOnLifecycleDestroyed |
La composizione verrà smaltita quando verrà eliminata la Lifecycle fornita.Scenario dell'interazione * ComposeView nella vista di un frammento. |
DisposeOnViewTreeLifecycleDestroyed |
La composizione verrà eliminata quando il Lifecycle di proprietà del LifecycleOwner restituito entro il ViewTreeLifecycleOwner.get della finestra successiva a cui è associata la vista viene eliminata.Scenario dell'interazione: * ComposeView nella vista di un frammento.* ComposeView in una vista in cui il ciclo di vita non è ancora noto. |
ComposeView
in frammenti
Se vuoi incorporare i contenuti dell'interfaccia utente di Compose in un frammento o in un layout di visualizzazione esistente, usa ComposeView
e chiama il relativo metodo setContent()
. ComposeView
è un View
Android.
Puoi inserire ComposeView
nel layout XML come qualsiasi altro 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>
Nel codice sorgente Kotlin, aumenta il layout della risorsa
layout definita nel file XML. Quindi recupera
ComposeView
utilizzando l'ID XML, imposta una strategia di composizione ottimale per
l'host View
e chiama setContent()
per utilizzare 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 } }
In alternativa, puoi anche utilizzare l'associazione di visualizzazioni per ottenere riferimenti a
ComposeView
, facendo riferimento alla classe di associazione generata per il file di layout 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 } }
Figura 1. Questo mostra l'output del codice che aggiunge elementi Compose in una gerarchia dell'UI di visualizzazione. Il testo "Ciao Android!" viene visualizzato da un widget TextView
. Il testo "Hello Compose!"
viene visualizzato da un elemento di testo Compose.
Puoi anche includere ComposeView
direttamente in un frammento se lo schermo intero è stato creato con Compose, il che ti consente di evitare di utilizzare completamente un file di layout 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!") } } } } }
Più istanze ComposeView
nello stesso layout
Se ci sono più elementi ComposeView
nello stesso layout, ognuno deve avere un
ID univoco affinché savedInstanceState
funzioni.
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 // ... } ) } }
Gli ID ComposeView
sono definiti nel file res/values/ids.xml
:
<resources> <item name="compose_view_x" type="id" /> <item name="compose_view_y" type="id" /> </resources>
Visualizza l'anteprima dei componibili nell'Editor layout
Puoi anche visualizzare l'anteprima dei componibili nell'Editor di layout per il layout XML che contiene un ComposeView
. In questo modo potrai vedere l'aspetto dei componibili
in un layout misto di Visualizzazioni e Compose.
Supponiamo che tu voglia visualizzare il seguente componibile nell'Editor layout. Tieni presente che i componibili annotati con @Preview
sono ideali per l'anteprima nell'Editor di layout.
@Preview @Composable fun GreetingPreview() { Greeting(name = "Android") }
Per visualizzare l'elemento componibile, utilizza l'attributo strumenti tools:composableName
e imposta il suo valore sul nome completo del componibile da visualizzare in anteprima nel layout.
<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>
Passaggi successivi
Ora che conosci le API di interoperabilità per utilizzare Compose in Views, scopri come utilizzare Views in Compose.
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Altre considerazioni
- Strategia di migrazione {:#migration-strategy}
- Confrontare il rendimento di Compose e View