Puoi aggiungere un'interfaccia utente basata su Compose a un'app esistente che utilizza un design basato su View.
Per creare una nuova schermata basata interamente su Compose, fai in modo che la tua
attività chiami il metodo setContent() e passa 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 è simile a quello che troveresti in un'app solo Compose.
ViewCompositionStrategy per ComposeView
ViewCompositionStrategy
definisce quando deve essere eliminata la composizione. Il valore predefinito,
ViewCompositionStrategy.Default,
elimina la composizione quando l'ComposeView
sottostante si scollega dalla finestra, a meno che non faccia parte di un contenitore di pooling come un
RecyclerView. In un'app con una sola attività basata su Compose, questo comportamento predefinito è
quello che vorresti, tuttavia, se stai aggiungendo Compose in modo incrementale nel tuo
codice base, 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 riepiloga i diversi scenari in cui puoi utilizzare
ViewCompositionStrategy:
ViewCompositionStrategy |
Descrizione e scenario di interoperabilità |
|---|---|
DisposeOnDetachedFromWindow |
La composizione verrà eliminata quando il ComposeView sottostante viene scollegato dalla finestra. È stato sostituito da DisposeOnDetachedFromWindowOrReleasedFromPool.Scenario di interoperabilità: * ComposeView se è l'unico elemento nella gerarchia della visualizzazione o nel contesto di una schermata mista View/Compose (non in Fragment). |
DisposeOnDetachedFromWindowOrReleasedFromPool (predefinito) |
Analogamente a DisposeOnDetachedFromWindow, quando la composizione non si trova in un contenitore di pooling, ad esempio un RecyclerView. Se si trova in un contenitore di pooling, viene eliminato quando il contenitore stesso si stacca dalla finestra o quando l'elemento viene eliminato (ad esempio quando il pool è pieno).Scenario di interoperabilità: * ComposeView se è l'unico elemento nella gerarchia View o nel contesto di una schermata mista View/Compose (non in Fragment).* ComposeView come elemento in un contenitore di pooling come RecyclerView. |
DisposeOnLifecycleDestroyed |
La composizione verrà eliminata quando il Lifecycle fornito viene distrutto.Scenario di interoperabilità * ComposeView nella visualizzazione di un fragment. |
DisposeOnViewTreeLifecycleDestroyed |
La composizione verrà eliminata quando Lifecycle di proprietà di LifecycleOwner restituito da ViewTreeLifecycleOwner.get della finestra successiva a cui è collegata la visualizzazione viene distrutto.Scenario di interoperabilità: * ComposeView nella visualizzazione di un fragment.* ComposeView in una visualizzazione in cui il ciclo di vita non è ancora noto. |
ComposeView in Frammenti
Se vuoi incorporare contenuti dell'interfaccia utente Compose in un fragment o in un layout View esistente, utilizza 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, gonfia il layout dalla risorsa
layout definita in XML. Poi recupera
ComposeView utilizzando l'ID XML, imposta una strategia di composizione più adatta
all'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 il binding della visualizzazione per ottenere riferimenti a
ComposeView facendo riferimento alla classe di binding 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. Mostra l'output del codice che aggiunge elementi Compose in una
gerarchia dell'interfaccia utente View. Il testo "Hello Android!" viene visualizzato da un widget TextView. Il testo "Hello Compose!" viene visualizzato da un
elemento di testo di Compose.
Puoi anche includere un ComposeView direttamente in un fragment se la schermata intera
è creata con Compose, il che ti consente di evitare di utilizzare 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 di ComposeView nello stesso layout
Se nello stesso layout sono presenti più elementi ComposeView, ognuno deve
avere un ID univoco per il funzionamento di savedInstanceState.
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>
Visualizzare l'anteprima dei componenti combinabili in Layout Editor
Puoi anche visualizzare l'anteprima dei composable nell'editor layout per il layout XML
contenente un ComposeView. In questo modo puoi vedere l'aspetto dei tuoi composable
all'interno di un layout misto di Views e Compose.
Supponiamo di voler visualizzare il seguente elemento componibile nell'editor layout. Nota
che i composable annotati con @Preview sono buoni candidati per l'anteprima nell'editor del layout.
@Preview @Composable fun GreetingPreview() { Greeting(name = "Android") }
Per visualizzare questo componente componibile, utilizza l'attributo tools:composableName tools e
imposta il relativo valore sul nome completo del componente 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.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Altre considerazioni
- Strategia di migrazione {:#migration-strategy}
- Confrontare la composizione e la visualizzazione del rendimento