É 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 precisa ser descartada. O padrão,
ViewCompositionStrategy.Default
,
descarta a composição quando o
ComposeView
subjacente se desanexa da janela, a menos que faça parte de um contêiner de pool, como um
RecyclerView
. Em um app de atividade única do Compose, esse comportamento padrão é
o que você quer. No entanto, se você estiver adicionando o Compose de forma incremental à sua
base de código, esse comportamento pode 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 é possível usar
ViewCompositionStrategy
:
ViewCompositionStrategy |
Descrição e cenário de interoperabilidade |
---|---|
DisposeOnDetachedFromWindow |
A composição será descartada quando o ComposeView de base for removido da janela. Foi substituído por DisposeOnDetachedFromWindowOrReleasedFromPool .Cenário de interoperabilidade: * ComposeView se é o único elemento na hierarquia de visualização ou no contexto de uma tela de visualização/composição mista (não no fragmento). |
DisposeOnDetachedFromWindowOrReleasedFromPool (padrão) |
Semelhante a DisposeOnDetachedFromWindow , quando a composição não está em um contêiner de agrupamento, como um RecyclerView . Se estiver em um contêiner de pool, ele será descartado quando o contêiner de pool se desconectar 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 de visualização/composição mista (não no 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 Interop * ComposeView na visualização de um fragmento. |
DisposeOnViewTreeLifecycleDestroyed |
A composição será descartada quando a Lifecycle pertencente à LifecycleOwner retornada por ViewTreeLifecycleOwner.get da próxima janela à qual a visualização está anexada for destruída.Cenário de interoperabilidade: * ComposeView na visualização de um 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
Você também pode visualizar os elementos combináveis no Layout Editor para o layout XML
que contém um ComposeView
. Isso permite que você veja como seus elementos combináveis
ficam em um layout misto de visualizações e Compose.
Digamos que você queira mostrar o elemento combinável a seguir no Layout Editor. 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 como o nome totalmente qualificado do elemento combinável para pré-visualizar 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 do View