Puoi aggiungere un'interfaccia utente basata su Compose a un'app esistente che utilizza un design basato su View.
Per creare una nuova schermata interamente basata su Compose, fai in modo che la tua attività chiami il metodo setContent()
e trasmetta le funzioni composable 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 è proprio come si trova in un'app di sola scrittura.
ViewCompositionStrategy
per ComposeView
ViewCompositionStrategy
definisce quando la composizione deve essere eliminata. Il valore predefinito,
ViewCompositionStrategy.Default
,
rimuove la composizione quando la
ComposeView
sottostante si scollegano dalla finestra, a meno che non facciano parte di un contenitore per il pooling come un
RecyclerView
. In un'app di sola scrittura di attività, questo comportamento predefinito è
cosa vorresti, tuttavia, se aggiungi in modo incrementale Compose nella
questo comportamento può causare la perdita di stato in alcuni scenari.
Per modificare ViewCompositionStrategy
, chiama setViewCompositionStrategy()
e fornire una strategia diversa.
La tabella seguente riassume i diversi scenari che puoi utilizzare
ViewCompositionStrategy
in:
ViewCompositionStrategy |
Descrizione e scenario di interoperabilità |
---|---|
DisposeOnDetachedFromWindow |
La composizione verrà eliminata quando l'elemento ComposeView sottostante viene scollegato dalla finestra. ed è stata sostituita da DisposeOnDetachedFromWindowOrReleasedFromPool .Scenario Interop: * ComposeView se è l'unico elemento nella gerarchia di visualizzazione o nel contesto di una schermata di tipo Visualizza/Scrivi (non in Frammento). |
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 pooling, verrà eliminato quando il container di pooling si scollega dalla finestra o quando l'elemento viene eliminato (ad es. quando il pool è pieno).Scenario Interop: * ComposeView se è l'unico elemento nella gerarchia di visualizzazione o nel contesto di una schermata di tipo Visualizza/Scrivi (non in Frammento).* ComposeView come elemento in un contenitore di pooling come RecyclerView . |
DisposeOnLifecycleDestroyed |
La composizione verrà eliminata quando l'oggetto Lifecycle fornito verrà distrutto.Scenario di interoperabilità * ComposeView nella visualizzazione di un frammento. |
DisposeOnViewTreeLifecycleDestroyed |
La composizione verrà eliminata quando l'elemento Lifecycle di proprietà di LifecycleOwner restituito da ViewTreeLifecycleOwner.get della finestra successiva a cui è collegata la vista viene distrutto.Scenario Interop: * ComposeView in una Vista frammento.* ComposeView in una visualizzazione 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 una vista esistente
utilizza ComposeView
e chiamare la sua
setContent()
. ComposeView
è una View
per Android.
Puoi inserire ComposeView
nel tuo 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 definita in XML. Quindi, recupera ComposeView
utilizzando l'ID XML, imposta una strategia di composizione più adatta all'View
host 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 delle visualizzazioni 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 gli elementi Compose in un
Visualizza la gerarchia dell'interfaccia utente. L'avviso "Hello Android!" viene visualizzato da un
Widget TextView
. Il prompt "Hello Compose!" viene visualizzato da un
Componi elemento di testo.
Puoi anche includere un ComposeView
direttamente in un frammento se la schermata completa è stata creata 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 nello stesso layout sono presenti più elementi ComposeView
, ognuno deve
dispongono di 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 componibili nell'Editor layout
Puoi anche visualizzare l'anteprima dei composabili nell'editor di layout per il layout XML contenente un ComposeView
. In questo modo puoi vedere l'aspetto dei tuoi composabili
in un layout misto di Visualizzazioni e Compose.
Supponiamo che tu voglia visualizzare il seguente composable nell'editor di layout. Tieni presente
che i composabili annotati con @Preview
sono buoni candidati per l'anteprima nell'Editor di layout.
@Preview @Composable fun GreetingPreview() { Greeting(name = "Android") }
Per visualizzare questo composable, utilizza l'attributo tools:composableName
tools e imposta il relativo valore sul nome completo del composable 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 nelle visualizzazioni, scopri come utilizzare le visualizzazioni in Compose.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Altre considerazioni
- Strategia di migrazione {:#migration-strategy}
- Confronto tra le prestazioni di Compose e Visualizza