Criar um app completo com o Relay e o Jetpack Compose

1. Antes de começar

O Relay (link em inglês) é um kit de ferramentas que ajuda equipes a projetar componentes de interface no Figma e usá-los diretamente em projetos do Jetpack Compose. Você não vai precisar mais de especificações longas de design nem ciclos de controle de qualidade para criar interfaces incríveis para Android com mais rapidez.

Neste codelab, vamos ensinar você a integrar pacotes de interface do Relay ao seu processo de desenvolvimento do Compose. Vamos focar nas técnicas de integração, e não no fluxo de trabalho completo. Para saber mais, confira o Tutorial básico do Relay.

Pré-requisitos

O que você vai aprender

  • Como importar pacotes de interface.
  • Como integrar pacotes de interface com a navegação e a arquitetura de dados.
  • Como unir pacotes de interface com a lógica do controlador.
  • Como mapear estilos do Figma para o tema do Compose.
  • Como substituir pacotes de interface com os combináveis existentes no código gerado.

O que você vai criar

  • Um design de app realista com base nos pacotes do Relay fornecidos por um designer. O app se chama Reflect e serve para promover mindfulness e bons hábitos no dia a dia. Ele contém uma coleção de itens que podem ser usados para criar lembretes e acompanhar suas atividades diárias e oferece uma interface para os gerenciar ou adicionar outros. O app vai ficar parecido com esta imagem:

O app final

O que é necessário

2. Começar a configuração

Buscar o código

Para encontrar o código deste codelab, realize uma destas ações:

$ git clone https://github.com/googlecodelabs/relay-codelabs
  • Navegue até o repositório relay-codelabs (link em inglês) no GitHub, selecione uma ramificação e clique em Code > Download zip, depois descompacte o arquivo ZIP transferido.

Em ambos os casos, a ramificação main contém o código inicial e a end contém o código da solução.

Instalar o plug-in do Relay para o Android Studio

Se ainda não tiver o plug-in do Relay para o Android Studio, siga estas etapas:

  1. No Android Studio, clique em Settings > Plugins.
  2. Digite Relay for Android Studio na caixa de texto.
  3. Clique em Install na extensão mostrada nos resultados da pesquisa.

Configurações do plug-in para o Android Studio

  1. Se uma caixa de diálogo Third-party plugins privacy note aparecer, clique em Accept.
  2. Clique em OK > Restart.
  3. Se uma caixa de diálogo Confirm exit aparecer, clique em Exit.

Conectar o Android Studio ao Figma

O Relay extrai pacotes de interface com a API Figma. Para usá-la, você precisa de uma conta gratuita no Figma e um token de acesso pessoal (links em inglês), como mencionamos na seção O que é necessário.

Caso ainda não tenha conectado o Android Studio ao Figma, siga estas etapas:

  1. Na conta do Figma, clique no ícone do perfil na parte de cima da página e selecione Settings.
  2. Na seção Personal access tokens, insira uma descrição na caixa de texto e pressione Enter (ou return no macOS). Um token será gerado.
  3. Clique em Copy this token.

Um token de acesso gerado no Figma

  1. No Android Studio, selecione Tools > Relay Settings. Uma caixa de diálogo Relay settings vai aparecer.
  2. Na caixa de texto Figma Access Token, cole o token de acesso e clique em OK. Seu ambiente está configurado.

3. Revisar o design do app

Trabalhamos com um designer para ajudar a definir a cor, o layout, a tipografia e o comportamento do app Reflect. Criamos os designs conforme as convenções do Material Design 3 para que o app funcione facilmente com os componentes e temas do Material Design.

Revisar a tela inicial

A tela inicial mostra uma lista de itens definidos pelo usuário. Ela também tem affordances para mudar o dia ativo e criar outros itens.

A tela inicial

No Figma, nosso designer dividiu a tela entre vários componentes, definiu as APIs e as empacotou com o Plug-in Relay para Figma (link em inglês). Você pode importar os componentes já empacotados para seu projeto no Android Studio.

Componente da tela inicial

Revisar a tela adicionar/editar

Essa tela permite que os usuários adicionem ou editem os itens. O formulário mostrado é um pouco diferente com base no tipo de item.

A tela adicionar/editar

De forma semelhante, a tela é dividida entre vários componentes empacotados.

Componentes da tela adicionar/editar

Revisar o tema

As cores e a tipografia para este design são implementadas como estilos do Figma com base nos nomes de token do Material Design 3. Isso proporciona uma interoperabilidade melhor entre os temas do Compose e os componentes do Material Design.

Estilos do Figma

4. Importar pacotes de interface

Antes de importar pacotes de interface para o projeto, é necessário fazer o upload da origem do design para o Figma.

Siga estas etapas para extrair o link da origem do Figma:

  1. No Figma, clique em Import file e selecione o arquivo ReflectDesign.fig localizado na pasta do projeto do codelab.
  2. Clique nele com o botão direito do mouse e selecione Copy link. Você vai precisar dele na próxima seção.

a98d24b4d5ee5c34.png

Importar pacotes de interface para o projeto

  1. No Android Studio, abra o projeto ./CompleteAppCodelab.
  2. Selecione File > New > Import UI Packages. Uma caixa de diálogo Import UI Packages vai aparecer.
  3. Na caixa de diálogo Figma source URL, cole o URL copiado na seção anterior.

A caixa de diálogo "Import UI Packages"

  1. Na caixa de texto App theme, insira com.google.relay.example.reflect.ui.theme.ReflectTheme. Isso garante que as visualizações geradas usem o tema personalizado.
  2. Clique em Next. Uma prévia dos pacotes da interface do arquivo vai aparecer.
  3. Clique em Create. Os pacotes serão importados para seu projeto.
  4. Navegue até a guia Project e clique na seta 2158ffa7379d2b2e.png ao lado da pasta ui-packages.

A pasta ui-packages

  1. Clique na seta 2158ffa7379d2b2e.png ao lado de uma das pastas de pacotes. Ela contém um arquivo de origem JSON e dependências de recursos.
  2. Abra o arquivo de origem JSON. O módulo do Relay mostra uma prévia do pacote e a API dele.

O módulo de prévia do pacote do Relay

Criar e gerar código

  1. Na parte de cima do Android Studio, clique em b3bc77f3c78cac1b.png Make project. O código gerado para cada pacote é adicionado ao arquivo java/com.google.relay.example.reflect. Os combináveis gerados contêm todas as informações de layout e estilo do design do Figma.
  2. Caso seja necessário, clique em Split para conferir os painéis de código e de prévia lado a lado.
  3. Abra o arquivo range/Range.kt. As prévias do Compose são criadas para cada variação de componente.

c0d21ab0622ad550.png

5. Integrar componentes

Nesta seção, detalhamos o código gerado para o botão do item.

O design para o botão

  1. No Android Studio, abra o arquivo com/google/relay/example/reflect/switch/Switch.kt.

Switch.kt (código gerado)

/**
 * This composable was generated from the switch UI Package.
 * Generated code; don't edit directly.
 */
@Composable
fun Switch(
    modifier: Modifier = Modifier,
    isChecked: Boolean = false,
    isPressed: Boolean = false,
    emoji: String = "",
    title: String = ""
) {
    TopLevel(modifier = modifier) {
        if (isChecked) {
            ActiveOverlay(modifier = Modifier.rowWeight(1.0f).columnWeight(1.0f)) {}
        }
        if (isPressed) {
            State(modifier = Modifier.rowWeight(1.0f).columnWeight(1.0f)) {}
        }
        TopLevelSynth {
            Label(modifier = Modifier.rowWeight(1.0f)) {
                Emoji(emoji = emoji)
                Title(
                    title = title,
                    modifier = Modifier.rowWeight(1.0f)
                )
            }
            if (isChecked) {
                Checkmark {
                    Vector(modifier = Modifier.rowWeight(1.0f).columnWeight(1.0f))
                }
            }
        }
    }
}
  1. Confira se:
  • Todo o layout e estilo do design do Figma foram gerados.
  • Os subcomponentes estão divididos em combináveis separados.
  • Prévias de elementos combináveis foram geradas para todas as variações de design.
  • Os estilos de cor e tipografia foram fixados no código. Você pode corrigir isso depois.

Inserir o item

  1. No Android Studio, abra o arquivo java/com/google/relay/example/reflect/ui/components/TrackerControl.kt. Ele fornece a lógica de dados e interação para items de hábitos. No momento, o componente gera dados brutos usando o modelo do item.

7850337c9ba23fd5.png

  1. Importe o pacote com.google.relay.example.reflect.switch.Switch para o arquivo.
  2. Crie um bloco when que recebe o campo trackerData.tracker.type como parâmetro.
  3. No corpo do bloco when, chame a função Switch() Composable quando o tipo for TrackerType.BOOLEAN.

O código ficará assim:

TrackerControl.kt

when (trackerData.tracker.type) {
    TrackerType.BOOLEAN ->
        Switch(
          title = trackerData.tracker.name,
          emoji = trackerData.tracker.emoji
        )
    else ->
        Text(trackerData.tracker.toString())
}
  1. Recrie o projeto. A página inicial vai renderizar o botão corretamente de acordo com o que foi projetado com dados reais.

f07eda1a7740129b.png

6. Adicionar estado e interação

Os pacotes de interface não têm estado. Eles simplesmente renderizam o resultado dos parâmetros transmitidos. No entanto, apps reais precisam de interação e estado. Os gerenciadores de interações podem ser transferidos para elementos combináveis como qualquer outro parâmetro, mas onde armazenamos o estado manipulado por eles? Como podemos evitar a transferência do mesmo gerenciador a todas as instâncias? Como abstrair composições de pacotes em combináveis que podem ser usados novamente? Nesses casos, recomendamos unir os pacotes gerados em uma função Composable personalizada.

Unir pacotes de interface em uma função Composable do controlador

A união de pacotes de interface em funções Composable do controlador ajuda a personalizar a apresentação ou a lógica de negócios e, se necessário, gerenciar o estado local. Os designers ainda podem atualizar o pacote original no Figma sem precisar pedir para você atualizar o código do wrapper.

Para criar um controlador para o botão do item, siga estas etapas:

  1. No Android Studio, abra o arquivo java/com/google/relay/example/reflect/ui/components/SwitchControl.kt.
  2. Na função SwitchControl() Composable, transmita estes parâmetros:
  • trackerData: um objeto TrackerData.
  • modifier: um objeto de decorador.
  • onLongClick: um callback de interação para ativar a ação "tocar e manter pressionado" nos itens para os editar ou excluir.

modifier

  1. Transmita um modificador combinedClickable para a função Switch() para processar as ações de "clicar" e "tocar e manter pressionado".
  2. Transmita valores do objeto TrackerData para a função Switch(), incluindo o método isToggled().

A função SwitchControl() concluída vai ficar parecida com este snippet de código:

SwitchControl.kt

package com.google.relay.example.reflect.ui.components

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.google.relay.example.reflect.model.Tracker
import com.google.relay.example.reflect.model.TrackerData
import com.google.relay.example.reflect.model.TrackerType
import com.google.relay.example.reflect.switch.Switch

/*
 * A component for controlling switch-type trackers.
 *
 * SwitchControl is responsible for providing interaction and state management to the stateless
 * composable [Switch] generated by Relay. [onLongClick] provides a way for callers to supplement
 * the control's intrinsic interactions with, for example, a context menu.
 */
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun SwitchControl(
    trackerData: TrackerData,
    modifier: Modifier = Modifier,
    onLongClick: (() -> Unit)? = null,
) {
    Switch(
        modifier
            .height(64.dp)
            .clip(shape = RoundedCornerShape(size = 32.dp))
            .combinedClickable(onLongClick = onLongClick) {
                trackerData.toggle()
            },
        emoji = trackerData.tracker.emoji,
        title = trackerData.tracker.name,
        isChecked = trackerData.isToggled(),
    )
}

@Preview
@Composable
fun SwitchControllerPreview() {
    val data = TrackerData(
        Tracker(
            emoji = "🍕",
            name = "Ate Pizza",
            type = TrackerType.BOOLEAN
        )
    )
    SwitchControl(data)
}
  1. No arquivo TrackerControl.kt, remova o Switch importado e substitua a função Switch() com uma chamada para a função SwitchControl().
  2. Adicione casos para as constantes TrackerType.RANGE e TrackerType.COUNT do enumerador.

O bloco when concluído vai ficar parecido com este snippet de código:

SwitchControl.kt

when (trackerData.tracker.type) {
    TrackerType.BOOLEAN ->
        SwitchControl(
            trackerData = trackerData,
            onLongClick = { expanded = true },
        )
    TrackerType.RANGE ->
        RangeControl(
            trackerData = trackerData,
            onLongClick = { expanded = true },
        )
    TrackerType.COUNT ->
        ValueControl(
            trackerData = trackerData,
            onLongClick = { expanded = true },
        )
}
  1. Recrie o projeto. Agora, você pode mostrar e interagir com os itens. A tela inicial está pronta.

b23b94f0034243d3.png

7. Mapear componentes já criados

O Relay ajuda os desenvolvedores a personalizar o código gerado substituindo pacotes de interface por elementos combináveis prontos. É uma ótima maneira de gerar componentes novos ou até mesmo personalizar sistemas de design no seu código.

Mapear um campo de texto

A imagem abaixo mostra o design do Switch Tracker Editor na caixa de diálogo Add/edit tracker (adicionar editar item):

Design do componente de configurações do botão

Nosso designer usou um ReflectTextField. Já temos uma implementação para esse componente no código criado com base nos campos de texto do Material Design 3. O Figma não oferece suporte nativo a campos de texto, então o modo padrão gerado pelo Relay só tem a aparência do design, não sendo um controle funcional.

Para substituir a implementação real por esse elemento, é necessário criar duas coisas: um pacote de interface de campo de texto e um arquivo de mapeamento. Felizmente, nosso designer já empacotou os componentes do sistema de design no Figma e usou um componente de botão para o Tracker Editor. Por padrão, esse pacote aninhado é gerado como dependência do pacote da barra de configurações, mas você pode usar o mapeamento de componentes para trocá-lo.

Componente do Figma para campo de texto com o plug-in do Relay sobreposto

Criar um arquivo de mapeamento

O plug-in do Relay para o Android Studio oferece um atalho para a criação de arquivos de mapeamento de componentes.

Para criar um deles, siga estas etapas:

  1. No Android Studio, clique com o botão direito do mouse no pacote de interface text_field e selecione Generate mapping file.

Geração do item do menu de contexto do arquivo de mapeamento

  1. Insira este código no arquivo:

text_field.json

{
  "target": "ReflectTextField",
  "package": "com.google.relay.example.reflect.ui.components",
  "generatePreviews": false
}

Os arquivos de mapeamento de componentes identificam um pacote e uma classe de destino do Compose, além de uma coleção opcional de objetos fieldMapping. Esses mapeamentos de campo possibilitam a transformação de parâmetros de pacotes nos parâmetros esperados do Compose. Nesse caso, as APIs são idênticas, então você só precisa identificar a classe de destino.

  1. Recrie o projeto.
  2. No arquivo trackersettings/ TrackerSettings.kt, localize a função combinável TitleFieldStyleFilledStateEnabledTextConfigurationsInputText() que foi gerada. Ela inclui um componente ReflectTextField gerado.

TrackerSettings.kt (gerado)

@Composable
fun TitleFieldStyleFilledStateEnabledTextConfigurationsInputText(
    onTitleChanged: (String) -> Unit,
    title: String,
    modifier: Modifier = Modifier
) {
    ReflectTextField(
        onChange = onTitleChanged,
        labelText = "Title",
        leadingIcon = "search",
        trailingIcon = "cancel",
        supportingText = "Supporting text",
        inputText = title,
        state = State.Enabled,
        textConfigurations = TextConfigurations.InputText,
        modifier = modifier.requiredHeight(56.0.dp)
    )
}

8. Mapear para temas do Compose

Por padrão, o Relay gera valores literais para cores e tipografia. Isso garante a precisão da translação, mas impede que os componentes usem o sistema de temas do Compose. Isso fica evidente quando abrimos o app no modo escuro:

Prévia da tela inicial no modo escuro mostrando as cores erradas

O componente de navegação que mostra o dia fica quase invisível e as cores estão erradas. Para corrigir isso, use o recurso de mapeamento de estilos do Relay para vincular os estilos do Figma aos tokens de tema do Compose no código gerado. Isso aumenta a consistência visual entre o Relay e os componentes do Material Design 3, além de ativar o suporte ao tema escuro.

1fac916db14929bb.png

Criar um arquivo de mapeamento de estilos

  1. No Android Studio, navegue até a pasta src/main/ui-package-resources/style-mappings e crie um arquivo figma_styles.json contendo este código:

figma_styles.json

{
  "figma": {
    "colors": {
      "Reflect Light/background": "md.sys.color.background",
      "Reflect Dark/background": "md.sys.color.background",
      "Reflect Light/on-background": "md.sys.color.on-background",
      "Reflect Dark/on-background": "md.sys.color.on-background",
      "Reflect Light/surface": "md.sys.color.surface",
      "Reflect Dark/surface": "md.sys.color.surface",
      "Reflect Light/on-surface": "md.sys.color.on-surface",
      "Reflect Dark/on-surface": "md.sys.color.on-surface",
      "Reflect Light/surface-variant": "md.sys.color.surface-variant",
      "Reflect Dark/surface-variant": "md.sys.color.surface-variant",
      "Reflect Light/on-surface-variant": "md.sys.color.on-surface-variant",
      "Reflect Dark/on-surface-variant": "md.sys.color.on-surface-variant",
      "Reflect Light/primary": "md.sys.color.primary",
      "Reflect Dark/primary": "md.sys.color.primary",
      "Reflect Light/on-primary": "md.sys.color.on-primary",
      "Reflect Dark/on-primary": "md.sys.color.on-primary",
      "Reflect Light/primary-container": "md.sys.color.primary-container",
      "Reflect Dark/primary-container": "md.sys.color.primary-container",
      "Reflect Light/on-primary-container": "md.sys.color.on-primary-container",
      "Reflect Dark/on-primary-container": "md.sys.color.on-primary-container",
      "Reflect Light/secondary-container": "md.sys.color.secondary-container",
      "Reflect Dark/secondary-container": "md.sys.color.secondary-container",
      "Reflect Light/on-secondary-container": "md.sys.color.on-secondary-container",
      "Reflect Dark/on-secondary-container": "md.sys.color.on-secondary-container",
      "Reflect Light/outline": "md.sys.color.outline",
      "Reflect Dark/outline": "md.sys.color.outline",
      "Reflect Light/error": "md.sys.color.error",
      "Reflect Dark/error": "md.sys.color.error"
    },
    "typography": {
      "symbols": {
        "Reflect/headline/large": "md.sys.typescale.headline-large",
        "Reflect/headline/medium": "md.sys.typescale.headline-medium",
        "Reflect/headline/small": "md.sys.typescale.headline-small",
        "Reflect/title/large": "md.sys.typescale.title-large",
        "Reflect/title/medium": "md.sys.typescale.title-medium",
        "Reflect/title/small": "md.sys.typescale.title-small",
        "Reflect/body/large": "md.sys.typescale.body-large",
        "Reflect/body/medium": "md.sys.typescale.body-medium",
        "Reflect/body/small": "md.sys.typescale.body-small",
        "Reflect/label/large": "md.sys.typescale.label-large",
        "Reflect/label/medium": "md.sys.typescale.label-medium",
        "Reflect/label/small": "md.sys.typescale.label-small"
      },
      "subproperties": {
        "fontFamily": "font",
        "fontWeight": "weight",
        "fontSize": "size",
        "letterSpacing": "tracking",
        "lineHeightPx": "line-height"
      }
    }
  },
  "compose": {
    "colors": {
      "md.sys.color.background": "MaterialTheme.colorScheme.background",
      "md.sys.color.error": "MaterialTheme.colorScheme.error",
      "md.sys.color.error-container": "MaterialTheme.colorScheme.errorContainer",
      "md.sys.color.inverse-on-surface": "MaterialTheme.colorScheme.inverseOnSurface",
      "md.sys.color.inverse-surface": "MaterialTheme.colorScheme.inverseSurface",
      "md.sys.color.on-background": "MaterialTheme.colorScheme.onBackground",
      "md.sys.color.on-error": "MaterialTheme.colorScheme.onError",
      "md.sys.color.on-error-container": "MaterialTheme.colorScheme.onErrorContainer",
      "md.sys.color.on-primary": "MaterialTheme.colorScheme.onPrimary",
      "md.sys.color.on-primary-container": "MaterialTheme.colorScheme.onPrimaryContainer",
      "md.sys.color.on-secondary": "MaterialTheme.colorScheme.onSecondary",
      "md.sys.color.on-secondary-container": "MaterialTheme.colorScheme.onSecondaryContainer",
      "md.sys.color.on-surface": "MaterialTheme.colorScheme.onSurface",
      "md.sys.color.on-surface-variant": "MaterialTheme.colorScheme.onSurfaceVariant",
      "md.sys.color.on-tertiary": "MaterialTheme.colorScheme.onTertiary",
      "md.sys.color.on-tertiary-container": "MaterialTheme.colorScheme.onTertiaryContainer",
      "md.sys.color.outline": "MaterialTheme.colorScheme.outline",
      "md.sys.color.primary": "MaterialTheme.colorScheme.primary",
      "md.sys.color.primary-container": "MaterialTheme.colorScheme.primaryContainer",
      "md.sys.color.secondary": "MaterialTheme.colorScheme.secondary",
      "md.sys.color.secondary-container": "MaterialTheme.colorScheme.secondaryContainer",
      "md.sys.color.surface": "MaterialTheme.colorScheme.surface",
      "md.sys.color.surface-variant": "MaterialTheme.colorScheme.surfaceVariant",
      "md.sys.color.tertiary": "MaterialTheme.colorScheme.tertiary",
      "md.sys.color.tertiary-container": "MaterialTheme.colorScheme.tertiaryContainer"
    },
    "typography": {
      "symbols": {
        "md.sys.typescale.display-large": "MaterialTheme.typography.displayLarge",
        "md.sys.typescale.display-medium": "MaterialTheme.typography.displayMedium",
        "md.sys.typescale.display-small": "MaterialTheme.typography.displaySmall",
        "md.sys.typescale.headline-large": "MaterialTheme.typography.headlineLarge",
        "md.sys.typescale.headline-medium": "MaterialTheme.typography.headlineMedium",
        "md.sys.typescale.headline-small": "MaterialTheme.typography.headlineSmall",
        "md.sys.typescale.title-large": "MaterialTheme.typography.titleLarge",
        "md.sys.typescale.title-medium": "MaterialTheme.typography.titleMedium",
        "md.sys.typescale.title-small": "MaterialTheme.typography.titleSmall",
        "md.sys.typescale.body-large": "MaterialTheme.typography.bodyLarge",
        "md.sys.typescale.body-medium": "MaterialTheme.typography.bodyMedium",
        "md.sys.typescale.body-small": "MaterialTheme.typography.bodySmall",
        "md.sys.typescale.label-large": "MaterialTheme.typography.labelLarge",
        "md.sys.typescale.label-medium": "MaterialTheme.typography.labelMedium",
        "md.sys.typescale.label-small": "MaterialTheme.typography.labelSmall"
      },
      "subproperties": {
        "font": "fontFamily",
        "weight": "fontWeight",
        "size": "fontSize",
        "tracking": "letterSpacing",
        "line-height": "lineHeight"
      }
    },
    "options": {
      "packages": {
        "MaterialTheme": "androidx.compose.material3"
      }
    }
  }
}

Os arquivos de mapeamento de tema são estruturados com dois objetos de nível superior: figma e compose. Dentro desses objetos, as definições de cor e tipo estão vinculadas entre os dois ambientes com tokens intermediários. Isso ajuda os estilos do Figma a mapearem uma única entrada de tema do Compose, o que é útil quando há suporte para os temas claro e escuro.

  1. Revise o arquivo de mapeamento, especialmente a forma como ele remapeia propriedades de tipografia do Figma para o que é esperado pelo Compose.

Importar pacotes de interface novamente

Depois de criar um arquivo de mapeamento, você precisa importar de novo todos os pacotes de interface para o projeto porque todos os valores de estilo do Figma foram descartados na importação inicial, já que nenhum arquivo de mapeamento foi fornecido.

Para importar os pacotes de interface novamente, siga estas etapas:

  1. No Android Studio, selecione File > New > Import UI Packages. Uma caixa de diálogo Import UI Packages vai aparecer.
  2. Na caixa de texto Figma source URL, insira o URL do arquivo de origem do Figma.
  3. Selecione a caixa Translate Figma styles to Compose theme.
  4. Clique em Next. Uma prévia dos pacotes da interface do arquivo vai aparecer.
  5. Clique em Create. Os pacotes serão importados para seu projeto.

A caixa de diálogo "Import UI Packages"

  1. Recrie o projeto, depois abra o arquivo switch/Switch.kt para acessar o código gerado.

Switch.kt (gerado)

@Composable
fun ActiveOverlay(
    modifier: Modifier = Modifier,
    content: @Composable RelayContainerScope.() -> Unit
) {
    RelayContainer(
        backgroundColor = MaterialTheme.colorScheme.surfaceVariant,
        isStructured = false,
        radius = 32.0,
        content = content,
        modifier = modifier.fillMaxWidth(1.0f).fillMaxHeight(1.0f)
    )
}
  1. Observe que o parâmetro backgroundColor está definido para o campo MaterialTheme.colorScheme.surfaceVariant no objeto de tema do Compose.
  2. No painel de visualização, troque para o tema escuro do app. O tema vai ser aplicado corretamente e os bugs visuais serão corrigidos.

6cf2aa19fabee292.png

9. Parabéns

Parabéns! Você aprendeu a integrar o Relay nos apps do Compose!

Saiba mais