1. Antes de começar
Desde o início, o Jetpack Compose foi criado com interoperabilidade de visualização, o que significa que ele e o sistema de visualização podem compartilhar recursos e trabalhar lado a lado para mostrar a interface. Essa funcionalidade permite adicionar o Compose ao seu app já existente baseado em visualização. Isso significa que o Compose e as visualizações podem coexistir na base de código até que todo o app esteja totalmente no Compose.
Neste codelab, você vai mudar o item de lista baseado em visualização no app Juice Tracker para usar o Compose. Você pode converter o restante das visualizações do Juice Tracker por conta própria, se quiser.
Se você tem um app que usa uma interface baseada em visualização, talvez não queira reprogramar toda a interface de uma vez. Este codelab ajuda a converter uma única visualização de uma interface baseada em visualização em um elemento do Compose.
Pré-requisitos
- Conhecer a interface baseada em visualização.
- Saber criar um app usando uma interface baseada em visualização.
- Ter experiência com a sintaxe do Kotlin, incluindo lambdas.
- Saber criar um app no Jetpack Compose.
O que você vai aprender
- Como adicionar o Compose a uma tela criada com visualizações do Android.
- Como visualizar um elemento combinável adicionado ao app baseado em visualização.
O que você vai criar
- Você vai converter um item de lista baseado em visualização para o Compose no app Juice Tracker.
2. Visão geral do app inicial
Este codelab usa o código de solução do app Juice Tracker mostrado em Criar um app Android com visualizações como o código inicial. O app inicial já salva dados usando a biblioteca de persistência Room. O usuário pode adicionar informações sobre sucos ao banco de dados do app, como nome, descrição, cor e nota.

Neste codelab, você vai converter o item de lista baseado em visualização para o Compose.

Fazer o download do código inicial para este codelab
Para começar, faça o download do código inicial:
Outra opção é clonar o repositório do GitHub:
$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-training-juice-tracker.git $ cd basic-android-kotlin-compose-training-juice-tracker $ git checkout views
Procure o código no repositório do GitHub do JuiceTracker (link em inglês).
3. Adicionar a biblioteca do Jetpack Compose
Não se esqueça, Compose e Views podem existir juntos em uma determinada tela. Você pode ter alguns elementos da interface no Compose e outros no sistema de visualização. Por exemplo, você pode ter apenas a lista no Compose e o restante da tela no sistema de visualização.
Conclua as etapas a seguir para adicionar a biblioteca do Compose ao app Juice Tracker.
- Abra o Juice Tracker no Android Studio.
- Abra o
build.gradle.ktsdo app. - No bloco
buildFeatures, adicione uma flagcompose = true.
buildFeatures {
//...
// Enable Jetpack Compose for this module
compose = true
}
Essa flag permite que o Android Studio funcione com o Compose. Você não realizou essa etapa nos codelabs anteriores, porque o Android Studio gera esse código automaticamente quando você cria um novo projeto de modelo do Compose no Android Studio.
- Abaixo de
buildFeatures, adicione o blococomposeOptions. - No bloco, defina
kotlinCompilerExtensionVersioncomo"1.5.1"para definir a versão do compilador Kotlin.
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
- Na seção
dependencies, adicione dependências do Compose. Você precisa das dependências a seguir para adicionar o Compose a um app baseado em visualização. Essas dependências ajudam a integrar o Compose à atividade, adicionar a biblioteca de componentes de design do Compose, oferecer suporte aos temas do Jetpack e fornecer ferramentas para melhorar o suporte ao ambiente de desenvolvimento integrado.
dependencies {
implementation(platform("androidx.compose:compose-bom:2023.06.01"))
// other dependencies
// Compose
implementation("androidx.activity:activity-compose:1.7.2")
implementation("androidx.compose.material3:material3")
implementation("com.google.accompanist:accompanist-themeadapter-material3:0.28.0")
debugImplementation("androidx.compose.ui:ui-tooling")
}
Adicionar ComposeView
Uma ComposeView é uma visualização do Android que pode hospedar conteúdo da interface do Jetpack Compose. Use setContent para fornecer a função combinável do conteúdo para a visualização.
- Abra o
layout/list_item.xmle confira a prévia na guia Split.
Ao final deste codelab, você vai substituir essa visualização por um elemento combinável.

- No
JuiceListAdapter.kt, removaListItemBindingde todos os lugares. Na classeJuiceListViewHolder, substituabinding.rootporcomposeView.
import androidx.compose.ui.platform.ComposeView
class JuiceListViewHolder(
private val onEdit: (Juice) -> Unit,
private val onDelete: (Juice) -> Unit
): RecyclerView.ViewHolder(composeView)
- Na pasta
onCreateViewHolder(), atualize a funçãoreturn()para que ela fique como este código:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): JuiceListViewHolder {
return JuiceListViewHolder(
ComposeView(parent.context),
onEdit,
onDelete
)
}
- Na classe
JuiceListViewHolder, exclua todas as variáveisprivatee remova todo o código da funçãobind(). A classeJuiceListViewHolderagora terá esta aparência:
class JuiceListViewHolder(
private val onEdit: (Juice) -> Unit,
private val onDelete: (Juice) -> Unit
) : RecyclerView.ViewHolder(composeView) {
fun bind(juice: Juice) {
}
}
- Agora, é possível excluir as importações
com.example.juicetracker.databinding.ListItemBindingeandroid.view.LayoutInflater.
// Delete
import com.example.juicetracker.databinding.ListItemBinding
import android.view.LayoutInflater
- Exclua o arquivo
layout/list_item.xml. - Selecione OK na caixa de diálogo Delete.

4. Adicionar função combinável
Agora, crie um elemento combinável que emita o item de lista. A função combinável usa Juice e duas funções de callback para editar e excluir o item de lista.
- No
JuiceListAdapter.kt, após a definição da classeJuiceListAdapter, crie uma função combinável chamadaListItem(). - Faça com que a função
ListItem()aceite o objetoJuicee um callback lambda para exclusão.
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
fun ListItem(
input: Juice,
onDelete: (Juice) -> Unit,
modifier: Modifier = Modifier
) {
}
Observe a prévia do item de lista que você quer criar. Ela mostra um ícone e detalhes do suco, além de um botão de exclusão. Você vai implementar esses componentes em breve.

Criar o elemento combinável do ícone de suco
- No
JuiceListAdapter.kt, depois do elemento combinávelListItem(), crie outra função combinável chamadaJuiceIcon()que usa umacolore umModifier.
@Composable
fun JuiceIcon(color: String, modifier: Modifier = Modifier) {
}
- Na função
JuiceIcon(), adicione variáveis para acolore a descrição do conteúdo, conforme mostrado no seguinte código:
@Composable
fun JuiceIcon(color: String, modifier: Modifier = Modifier) {
val colorLabelMap = JuiceColor.values().associateBy { stringResource(it.label) }
val selectedColor = colorLabelMap[color]?.let { Color(it.color) }
val juiceIconContentDescription = stringResource(R.string.juice_color, color)
}
Usando as variáveis colorLabelMap e selectedColor, você vai recuperar o recurso de cores associado à seleção do usuário.
- Adicione um layout
Boxpara mostrar dois íconesic_juice_coloreic_juice_clear, um sobre o outro. O íconeic_juice_colortem uma tonalidade e está alinhado ao centro.
import androidx.compose.foundation.layout.Box
Box(
modifier.semantics {
contentDescription = juiceIconContentDescription
}
) {
Icon(
painter = painterResource(R.drawable.ic_juice_color),
contentDescription = null,
tint = selectedColor ?: Color.Red,
modifier = Modifier.align(Alignment.Center)
)
Icon(painter = painterResource(R.drawable.ic_juice_clear), contentDescription = null)
}
Como você já conhece a implementação de um elemento combinável, os detalhes sobre essa etapa não são fornecidos.
- Adicione uma função para visualizar
JuiceIcon(). Transmita a cor comoYellow.
import androidx.compose.ui.tooling.preview.Preview
@Preview
@Composable
fun PreviewJuiceIcon() {
JuiceIcon("Yellow")
}

Criar elementos combináveis de detalhes do suco
No JuiceListAdapter.kt, é necessário adicionar outra função combinável para mostrar os detalhes do suco. Você também precisa de um layout de coluna para mostrar dois elementos combináveis Text para o nome e a descrição, além de um indicador de nota. Para isso, siga estas etapas:
- Adicione uma função combinável com o nome
JuiceDetails(), que usa um objetoJuicee umModifier, além de um elemento combinável de texto para o nome e outro para a descrição do suco, conforme mostrado no código abaixo:
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.ui.text.font.FontWeight
@Composable
fun JuiceDetails(juice: Juice, modifier: Modifier = Modifier) {
Column(modifier, verticalArrangement = Arrangement.Top) {
Text(
text = juice.name,
style = MaterialTheme.typography.h5.copy(fontWeight = FontWeight.Bold),
)
Text(juice.description)
RatingDisplay(rating = juice.rating, modifier = Modifier.padding(top = 8.dp))
}
}
- Para resolver o erro de referência, crie uma função combinável chamada
RatingDisplay().

No sistema de visualização, você tem uma RatingBar para mostrar a barra de nota a seguir. Como o Compose não tem um elemento combinável da barra de nota, é necessário implementar esse elemento do zero.
- Defina a função
RatingDisplay()para mostrar as estrelas de acordo com a nota. Essa função combinável mostra o número de estrelas com base na classificação.

import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.pluralStringResource
@Composable
fun RatingDisplay(rating: Int, modifier: Modifier = Modifier) {
val displayDescription = pluralStringResource(R.plurals.number_of_stars, count = rating)
Row(
// Content description is added here to support accessibility
modifier.semantics {
contentDescription = displayDescription
}
) {
repeat(rating) {
// Star [contentDescription] is null as the image is for illustrative purpose
Image(
modifier = Modifier.size(32.dp),
painter = painterResource(R.drawable.star),
contentDescription = null
)
}
}
}
Para criar o drawable de estrela no Compose, é necessário criar o recurso de vetor de estrelas.
- No painel Project, clique com o botão direito do mouse em drawable > New > Vector Asset.

- Na caixa de diálogo do Asset Studio, procure um ícone de estrela. Selecione o ícone de estrela preenchida.


- Mude o valor de cor da estrela para 625B71.

- Clique em Next > Finish.
- Um drawable aparece na pasta
res/drawable.

- Adicione um elemento combinável de prévia para
JuiceDetails.
@Preview
@Composable
fun PreviewJuiceDetails() {
JuiceDetails(Juice(1, "Sweet Beet", "Apple, carrot, beet, and lemon", "Red", 4))
}

Criar um elemento combinável do botão de exclusão
- No
JuiceListAdapter.kt, adicione outra função combinável chamadaDeleteButton(), que usa uma função de callback de lambda e um modificador. - Defina a lambda como o argumento
onClicke transmita oIcon()conforme mostrado no seguinte código:
import androidx.compose.ui.res.painterResource
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@Composable
fun DeleteButton(onDelete: () -> Unit, modifier: Modifier = Modifier) {
IconButton(
onClick = { onDelete() },
modifier = modifier
) {
Icon(
painter = painterResource(R.drawable.ic_delete),
contentDescription = stringResource(R.string.delete)
)
}
}
- Adicione uma função de prévia para o botão de exclusão.
@Preview
@Composable
fun PreviewDeleteIcon() {
DeleteButton({})
}

5. Implementar a função ListItem
Agora que você tem todos os elementos combináveis necessários para mostrar o item de lista, eles podem ser organizados em um layout. Observe a função ListItem() definida na etapa anterior.
@Composable
fun ListItem(
input: Juice,
onEdit: (Juice) -> Unit,
onDelete: (Juice) -> Unit,
modifier: Modifier = Modifier
) {
}
No JuiceListAdapter.kt, conclua as etapas a seguir para implementar a função ListItem().
- Adicione um layout
Rowdentro do lambdaMdc3Theme {}.
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import com.google.accompanist.themeadapter.material3.Mdc3Theme
Mdc3Theme {
Row(
modifier = modifier,
horizontalArrangement = Arrangement.SpaceBetween
) {
}
}
- No lambda
Row, chame os três elementos combináveis (JuiceIcon,JuiceDetailseDeleteButton) que você criou como elementos filhos.
JuiceIcon(input.color)
JuiceDetails(input, Modifier.weight(1f))
DeleteButton({})
A transmissão do Modifier.weight(1f) para o elemento combinável JuiceDetails() garante que os detalhes do suco ocupem o espaço horizontal restante depois de medir os elementos filhos sem peso.
- Transmita a lambda
onDelete(input)e o modificador com alinhamento superior como parâmetros para o elemento combinávelDeleteButton.
DeleteButton(
onDelete = {
onDelete(input)
},
modifier = Modifier.align(Alignment.Top)
)
- Crie uma função de prévia para o elemento combinável
ListItem.
@Preview
@Composable
fun PreviewListItem() {
ListItem(Juice(1, "Sweet Beet", "Apple, carrot, beet, and lemon", "Red", 4), {})
}

- Vincule o elemento combinável
ListItemao armazenador de visualização. ChameonEdit(input)na função lambdaclickable()para abrir a caixa de diálogo de edição quando houver um clique no item da lista.
Na classe JuiceListViewHolder, dentro da função bind(), você precisa hospedar o elemento combinável. Use a ComposeView, que é uma visualização do Android que pode hospedar conteúdo da interface do Compose utilizando o método setContent.
fun bind(input: Juice) {
composeView.setContent {
ListItem(
input,
onDelete,
modifier = Modifier
.fillMaxWidth()
.clickable {
onEdit(input)
}
.padding(vertical = 8.dp, horizontal = 16.dp),
)
}
}
- Execute o app e adicione seu suco favorito. Observe o item de lista do Compose.
. 
Parabéns! Você acabou de criar seu primeiro app de interoperabilidade do Compose que usa elementos do Compose em um app baseado em visualização.
6. Acessar o código da solução
Para baixar o código do codelab concluído, use estes comandos git:
$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-training-juice-tracker.git $ cd basic-android-kotlin-compose-training-juice-tracker $ git checkout views-with-compose
Se preferir, você pode baixar o repositório como um arquivo ZIP, descompactar e abrir no Android Studio.
Se você quiser conferir o código da solução, acesse o GitHub (link em inglês).
7. Saiba mais
Documentação do desenvolvedor Android
- Ferramentas para Compose | Jetpack Compose | Desenvolvedores Android
- APIs de interoperabilidade | Jetpack Compose | Desenvolvedores Android
- Estratégia de migração | Jetpack Compose | Desenvolvedores Android
Codelab [intermediário]