É possível adicionar uma interface com base no Compose a um app já existente que usa um design com base em visualização.
Para criar uma tela totalmente baseada no Compose, faça sua
atividade chamar o método setContent() e transmitir as
funções combináveis que você quer usar.
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!") }
Esse código é parecido com o que você encontraria em um app feito inteiramente com o Compose.
ViewCompositionStrategy por ComposeView
ViewCompositionStrategy
define quando a composição deve ser descartada. O padrão,
ViewCompositionStrategy.Default,
descarta a composição quando o
ComposeView
é desanexado da janela, a menos que faça parte de um contêiner de pool, como um
RecyclerView. Em um app de atividade única somente com Compose, esse comportamento padrão é
o que você quer. No entanto, se você estiver adicionando o Compose de forma incremental na sua
base de código, esse comportamento poderá causar perda de estado em alguns cenários.
Para mudar o ViewCompositionStrategy, chame o método setViewCompositionStrategy() e forneça uma estratégia diferente.
A tabela abaixo resume os diferentes cenários em que você pode usar
ViewCompositionStrategy:
ViewCompositionStrategy |
Descrição e cenário de interoperabilidade |
|---|---|
DisposeOnDetachedFromWindow |
A composição será descartada quando o ComposeView subjacente for removido da janela. Desde então, foi substituído por DisposeOnDetachedFromWindowOrReleasedFromPool.Cenário de interoperabilidade: * ComposeView, seja o único elemento na hierarquia de visualização ou no contexto de uma tela mista de visualização/Compose (não em Fragment). |
DisposeOnDetachedFromWindowOrReleasedFromPool (padrão) |
Semelhante a DisposeOnDetachedFromWindow, quando a composição não está em um contêiner de pooling, como um RecyclerView. Se ele estiver em um contêiner de agrupamento, será descartado quando o contêiner se separar da janela ou quando o item for descartado (ou seja, quando o pool estiver cheio).Cenário de interoperabilidade: * ComposeView se é o único elemento na hierarquia de visualização ou no contexto de uma tela mista de visualização/composição (não em um fragmento).* ComposeView como um item em um contêiner de agrupamento, como RecyclerView. |
DisposeOnLifecycleDestroyed |
A composição será descartada quando o Lifecycle fornecido for destruído.Cenário de interoperabilidade * ComposeView na visualização de um fragmento. |
DisposeOnViewTreeLifecycleDestroyed |
A composição será descartada quando o Lifecycle pertencente ao LifecycleOwner retornado por ViewTreeLifecycleOwner.get da próxima janela a que a visualização está anexada for destruído.Cenário de interoperabilidade: * ComposeView em uma visualização de fragmento.* ComposeView em uma visualização em que o ciclo de vida ainda não é conhecido. |
ComposeView em fragmentos
Se você quiser incorporar o conteúdo da interface do Compose em um fragmento ou um layout de visualização
já existente, use ComposeView
e chame o método
setContent()
dele. ComposeView é uma View para Android.
Você pode colocar a ComposeView no seu layout XML como qualquer outra 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>
No código-fonte do Kotlin, infle o layout usando o recurso
de layout definido no XML. Em seguida, acesse a
ComposeView usando o ID do XML, defina uma estratégia de composição que funcione melhor para
a View host e chame setContent() para usar o 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 } }
Como alternativa, você também pode usar a vinculação de visualizações para acessar referências ao
ComposeView referenciando a classe de vinculação gerada para seu arquivo de 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. Isso mostra a saída do código que adiciona elementos do Compose a uma
hierarquia de interface de visualização. A mensagem "Hello Android!" é exibida por um
widget TextView. A mensagem "Hello Compose!" é exibida por um
elemento de texto do Compose.
Também será possível incluir uma ComposeView diretamente em um fragmento se a tela cheia
for criada com o Compose, o que permite evitar totalmente o uso de um arquivo de 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!") } } } } }
Várias instâncias de ComposeView no mesmo layout
Se houver vários elementos ComposeView no mesmo layout, cada um precisará ter um
ID exclusivo para que o savedInstanceState funcione.
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 // ... } ) } }
Os IDs ComposeView são definidos no arquivo res/values/ids.xml:
<resources> <item name="compose_view_x" type="id" /> <item name="compose_view_y" type="id" /> </resources>
Visualizar elementos combináveis no Layout Editor
Também é possível conferir uma prévia dos elementos combináveis no Layout Editor para seu layout XML
que contém um ComposeView. Assim, você pode ver como os elementos combináveis ficam
em um layout misto de visualizações e Compose.
Suponha que você queira mostrar o seguinte elemento combinável no Layout Editor. Observação
Os elementos combináveis anotados com @Preview são bons candidatos para visualização no
Layout Editor.
@Preview @Composable fun GreetingPreview() { Greeting(name = "Android") }
Para mostrar esse elemento combinável, use o atributo de ferramentas tools:composableName e
defina o valor dele como o nome totalmente qualificado do elemento combinável a ser visualizado no
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>

Próximas etapas
Agora que você aprendeu sobre as APIs de interoperabilidade para usar o Compose em visualizações, saiba como usar as visualizações no Compose.
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Outras considerações
- Estratégia de migração {:#migration-strategy}
- Comparar a performance do Compose e da visualização