É 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
sai da janela, a menos que faça parte de um contêiner de pooling, como um
RecyclerView
. Em um app que tenha apenas uma atividade do Compose, esse comportamento padrão é
No entanto, se você adicionar 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 fornecer uma estratégia diferente.
A tabela abaixo resume os diferentes cenários que podem ser usados
ViewCompositionStrategy
em:
ViewCompositionStrategy |
Descrição e cenário de interoperabilidade |
---|---|
DisposeOnDetachedFromWindow |
A composição será descartada quando a ComposeView for removida da janela. Desde então, foi substituído por DisposeOnDetachedFromWindowOrReleasedFromPool .Cenário de interoperabilidade: * ComposeView se ele é o único elemento na hierarquia de visualização ou no contexto de uma tela mista de visualização/Compose (não no fragmento). |
DisposeOnDetachedFromWindowOrReleasedFromPool (Padrão) |
Semelhante a DisposeOnDetachedFromWindow , quando a composição não está em um contêiner de pool, como um RecyclerView . Se estiver em um contêiner de pool, ele será descartado quando o próprio contêiner de pool for removido da janela ou quando o item estiver sendo descartado (ou seja, quando o pool estiver cheio).Cenário de interoperabilidade: * ComposeView se ele for o único elemento na hierarquia de visualização ou no contexto de uma tela mista de visualização/Compose (não no fragmento).* ComposeView como um item em um contêiner de pool, 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 de propriedade do LifecycleOwner retornado por ViewTreeLifecycleOwner.get da próxima janela em que a visualização for anexada for destruído.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, também é possível usar a vinculação de visualizações para obter referências às
ComposeView
referenciando a classe de vinculação gerada para o 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 visualizar elementos combináveis no Layout Editor para seu layout XML.
contendo um ComposeView
. Isso permite conferir a aparência dos elementos combináveis
em um layout misto de visualizações e do Compose.
Digamos que você queira mostrar o seguinte elemento combinável no Layout Editor. Observação
que os elementos combináveis anotados com @Preview
são bons candidatos para visualização na
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 para visualização na
o mesmo layout organizacional.
<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 o desempenho do Compose e da visualização