DEV Community

Cover image for Como desenhar telas no Jetpack Compose
Alex Felipe
Alex Felipe

Posted on

18 1 1

Como desenhar telas no Jetpack Compose

O Jetpack Compose é uma ferramenta bastante poderosa para criar telas nativas no Android.

Embora a ideia da ferramenta seja facilitar a implementação de telas, se não compreendermos a finalidade de cada componente, não será uma tarefa fácil!

Considerando esses detalhes, vamos entender como devemos pensar no momento que criamos uma tela.

Amostra de implementação

Como demonstração, vamos utilizar a seguinte tela:

Preview de um card com bordas arredondas, imagem no topo preenchendo toda a largura do card, abaixo em layout de coluna, contém o título, subtítulo, ícone de favorito e botão com mensagem 'ler agora'. ícone de favorito e botão estão em layout de linha, sendo que o ícone está na extrema esquerda e botão na extrema direita

Agora que conhecemos a tela, precisamos compreender a lógica de analise antes de começar a implementação.

Identificando os elementos visuais

Como primeiro passo, podemos começar a analise identificando os elementos visuais. De uma forma genérica, temos:

  • imagem de capa
  • texto de título
  • texto de subtítulo
  • ícone de favorito
  • botão de leitura

Analisando o layout da tela

Então, precisamos analisar o layout geral. Observe que todos os elementos estão organizados em coluna, sendo que o ícone e botão, estão em linha!

Com apenas essa analise, podemos implementar o primeiro código da tela com composable de layout:

Column {
    AsyncImage(
        "https://picsum.photos/1920/1080",
        contentDescription = "Imagem de capa"
    )
    Text(text = "Título")
    Text(text = "Subtitulo")
    Row {
        Icon(
            Icons.Outlined.FavoriteBorder,
            contentDescription = "ícone de favorito"
        )
        Button(onClick = { /*TODO*/ }) {
            Text(text = "Ler agora")
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

App em execução apresentando a tela com imagem, título, subtítulo, ícone e botão no layout de coluna. Ícone e botão no layout em linha

Embora o design não esteja fiel a amostra, já temos tudo que precisamos para seguir com o próximo passo, personalizar os componentes da tela.

Fazendo uma analogia ao front-end na web, basicamente, adicionamos o HTML para estruturar a página!

Personalizando a tela com o Modifier

Assim como há os composables para estruturar a tela, temos o Modifier como entidade responsável em personalizar, dar comportamentos e reagir a eventos dos composables. Sendo assim, vamos utilizá-lo para modificar os composables

Seguindo a analogia com front-end, o Modifier seria um CSS do Jetpack Compose.

Ajustando o container principal

Podemos começar a personalização por qualquer componente, mas, geralmente tendo seguir uma estratégia, começar pelo componente mais externo até o mais interno, portanto, vamos começar com o Column mais externo:

Column(
    Modifier
        .padding(8.dp)
        .fillMaxWidth()
        .border(
            0.5.dp,
            Color.Gray.copy(alpha = 0.5f),
            RoundedCornerShape(20.dp)
        )
) {
    ...
}
Enter fullscreen mode Exit fullscreen mode

App em execução apresentado o card com espaçamento entre as extremidades da tela e bordas arredondadas

Todo composable recebe como primeiro parâmetro opcional um Modifier, pois existe o Modifier padrão. Para mais detalhes, você pode verificar nesta thread sobre modificadores..

Note que agora já temos um destaque ao container que representa o card, exibindo um espaçamento e bordas arredondadas.

Personalizando a imagem de capa

Por mais que o container do card foi ajustado corretamente, a imagem ainda apresenta o aspecto quadrado e ultrapassa as extremidades do container principal, para resolver isso, podemos aplicar o modificador na imagem também:

Column(
    ...
) {
    AsyncImage(
        "https://picsum.photos/1920/1080",
        contentDescription = "Imagem de capa",
        Modifier
            .height(100.dp)
            .clip(
                RoundedCornerShape(
                    topStart = 20.dp,
                    topEnd = 20.dp
                )
            ),
        contentScale = ContentScale.Crop,
        placeholder = ColorPainter(Color.Gray)
    )
    ...
}
Enter fullscreen mode Exit fullscreen mode

Card e imagem de capa com as bordas arredondadas

Note que além do modificador, utilizei alguns parâmetros próprios do AsyncImage:

  • contentScale: o container da imagem vai ter uma altura fixa, na escala padrão, ela fica distorcida ao tentar exibir todo conteúdo da imagem. Aplicando o corte com o ContentScale.Crop, apresenta a imagem cortada no espaço disponível.
  • placeholder: apresenta conteúdo no preview e durante o carregamento da imagem via internet, nesse caso, um fundo cinza

Agora que a imagem de capa foi ajustada, vamos para os textos.

Modificando os textos

Podemos modificar os textos da seguinte maneira:

Column(
    ...
) {
    ...
    Text(
        text = "Título",
        Modifier.padding(
            start = 16.dp,
            top = 16.dp,
            end = 16.dp,
            bottom = 8.dp
        ),
        fontSize = 24.sp
    )
    Text(
        text = "Subtitulo",
        Modifier.padding(
            start = 16.dp,
            end = 16.dp,
            bottom = 16.dp
        ),
        fontSize =
        14.sp
    )
    ...
}

}
Enter fullscreen mode Exit fullscreen mode

Card aplicando espaçamento e tamanho de fonte no título e subtitulo

Mesmo que os textos foram modificados como esperado, é válido notar que tivemos que aplicar diversos números para o espaçamento...

Em casos como esses, podemos utilizar composables de layout para simplificar a implementação, como por exemplo, envolver os Texts em coluna e modificar o espaçamento da coluna e ajustar o arranjo vertical:

Column(
    ...
) {
    ...
    Column(
        Modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        Text(
            text = "Título",
            fontSize = 24.sp
        )
        Text(
            text = "Subtitulo",
            fontSize = 14.sp
        )
    }
    ...
}
Enter fullscreen mode Exit fullscreen mode

Tanto o Row como o Column, possuem parâmetros extras para manipular os seus filhos, ou seja, os composables que são organizados por eles.

Com esse ajuste, temos o mesmo resultado de antes! Mais simples, concorda? Por fim, precisamos apenas ajustar a linha final.

Ajustando o ícone e botão em linha

O ajuste da linha é bastante similar ao que fizemos na coluna anterior:

Column(
    ...
) {
    ...
    Row(
        Modifier
            .padding(16.dp)
            .fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(
            Icons.Outlined.FavoriteBorder,
            contentDescription = "ícone de favorito"
        )
        Button(onClick = { /*TODO*/ }) {
            Text(text = "Ler agora")
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Card com o ícone de favorito e botão para ler em linha alinhados nas extremidades da tela, sendo o ícone a esquerda e botão direito na direita. Também, com espaçamento aplicado

A grande diferença fica na aplicação da largura com o fillMaxWidth() em conjunto do arranjo e alinhamento.

Essa técnica é utilizada para que seja possível aplicar o Arrangement.SpaceBetween que organiza os filhos nas extremidades, já o alinhamento, centraliza os filhos verticalmente.

Conclusão

Em um primeiro momento, a implementação de telas no Jetpack Compose pode parecer complexa, porém, vimos que podemos aplicar algumas técnicas para facilitar a escrita de código.

Considerando o que vimos, temos:

  • identificação dos elementos visuais
  • analise do layout
  • aplicação de modificadores em cada componente
  • ordem de modificação para facilitar

O que achou de criar telas no Jetpack Compose? Você já usa essas técnicas ou tem outros macetes para facilitar a implementação?

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (1)

Collapse
 
rodrocksoftware profile image
Rodrigo Rodrock

Parabéns pelo conteúdo de alta qualidade Felipe. Sucesso!

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay