Dica

Use dicas para adicionar contexto a um botão ou outro elemento da interface. Há dois tipos de dicas:

  • Dicas de ferramentas simples: descrevem elementos ou ações de botões de ícone.
  • Dicas avançadas: oferecem mais detalhes, como a descrição do valor de um recurso. Também é possível incluir um título, um link e botões opcionais.
Dica simples de uma linha com o rótulo (1) e uma dica avançada de várias linhas com um título e um bloco de informações com o rótulo (2).
Figura 1. Uma dica simples (1) e uma dica avançada (2).

Superfície da API

Você pode usar o elemento combinável TooltipBox para implementar dicas no seu app. Controle a aparência de TooltipBox com estes parâmetros principais:

  • positionProvider: posiciona a dica em relação ao conteúdo da âncora. Normalmente, você usa um provedor de posição padrão do TooltipDefaults, mas também pode fornecer o seu próprio se precisar de uma lógica de posicionamento personalizada.
  • tooltip: o elemento combinável que contém o conteúdo da dica. Normalmente, você usa os elementos combináveis PlainTooltip ou RichTooltip.
    • Use PlainTooltip para descrever elementos ou ações de botões de ícone.
    • Use RichTooltip para fornecer mais detalhes, como descrever o valor de um recurso. As dicas avançadas podem incluir um título, um link e botões opcionais.
  • state: o detentor de estado que contém a lógica da interface e o estado do elemento para essa dica.
  • content: o conteúdo combinável a que a dica está ancorada.

Mostrar uma dica simples

Use uma dica simples para descrever brevemente um elemento da interface. Este snippet de código mostra uma dica simples em cima de um botão de ícone, chamado "Adicionar aos favoritos":

@Composable
fun PlainTooltipExample(
    modifier: Modifier = Modifier,
    plainTooltipText: String = "Add to favorites"
) {
    TooltipBox(
        modifier = modifier,
        positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
        tooltip = {
            PlainTooltip { Text(plainTooltipText) }
        },
        state = rememberTooltipState()
    ) {
        IconButton(onClick = { /* Do something... */ }) {
            Icon(
                imageVector = Icons.Filled.Favorite,
                contentDescription = "Add to favorites"
            )
        }
    }
}

Pontos principais sobre o código

  • TooltipBox gera uma dica com o texto "Adicionar aos favoritos".
  • O IconButton cria um botão clicável com um ícone.
    • Icon(...) mostra um ícone de coração dentro do botão.
    • Quando um usuário interage com o IconButton, o TooltipBox mostra a dica com o texto "Adicionar aos favoritos". Dependendo do dispositivo, os usuários podem acionar a dica das seguintes maneiras:
    • Passar o cursor sobre o ícone
    • Tocar e manter pressionado o ícone em um dispositivo móvel

Resultado

Este exemplo produz uma dica simples em cima de um ícone:

Dica de uma linha com o texto
Figura 2. Uma dica simples que aparece quando um usuário passa o cursor ou toca e mantém pressionado o ícone de coração.

Mostrar uma dica avançada

Use uma dica avançada para fornecer mais contexto sobre um elemento da interface. Este exemplo cria uma dica avançada de várias linhas com um título ancorado a um Icon:

@Composable
fun RichTooltipExample(
    modifier: Modifier = Modifier,
    richTooltipSubheadText: String = "Rich Tooltip",
    richTooltipText: String = "Rich tooltips support multiple lines of informational text."
) {
    TooltipBox(
        modifier = modifier,
        positionProvider = TooltipDefaults.rememberRichTooltipPositionProvider(),
        tooltip = {
            RichTooltip(
                title = { Text(richTooltipSubheadText) }
            ) {
                Text(richTooltipText)
            }
        },
        state = rememberTooltipState()
    ) {
        IconButton(onClick = { /* Icon button's click event */ }) {
            Icon(
                imageVector = Icons.Filled.Info,
                contentDescription = "Show more information"
            )
        }
    }
}

Pontos principais sobre o código

  • O TooltipBox processa os listeners de eventos para interações do usuário e atualiza TooltipState de acordo. Quando TooltipState indica que a dica precisa ser mostrada, a lambda da dica é executada, e TooltipBox mostra o RichTooltip. O TooltipBox funciona como âncora e contêiner para o conteúdo e a dica.
    • Nesse caso, o conteúdo é um componente IconButton, que fornece o comportamento de ação de toque. Quando pressionada por muito tempo (em dispositivos touch) ou passada por cima (com o ponteiro do mouse) em qualquer lugar do conteúdo de TooltipBox, a dica vai aparecer para mostrar mais informações.
  • O elemento combinável RichTooltip define o conteúdo da dica, incluindo o título e o texto do corpo. O TooltipDefaults.rememberRichTooltipPositionProvider() fornece informações de posicionamento para dicas avançadas.

Resultado

Este exemplo produz uma dica avançada com um título anexado a um ícone de informações:

Uma dica de várias linhas com o título
Figura 3. Uma dica avançada com um título e um ícone de informações.

Personalizar uma dica avançada

Este snippet de código mostra uma dica avançada com um título, ações personalizadas e um cursor (seta) personalizado exibido em cima de um botão de ícone de câmera:

@Composable
fun AdvancedRichTooltipExample(
    modifier: Modifier = Modifier,
    richTooltipSubheadText: String = "Custom Rich Tooltip",
    richTooltipText: String = "Rich tooltips support multiple lines of informational text.",
    richTooltipActionText: String = "Dismiss"
) {
    val tooltipState = rememberTooltipState()
    val coroutineScope = rememberCoroutineScope()

    TooltipBox(
        modifier = modifier,
        positionProvider = TooltipDefaults.rememberRichTooltipPositionProvider(),
        tooltip = {
            RichTooltip(
                title = { Text(richTooltipSubheadText) },
                action = {
                    Row {
                        TextButton(onClick = {
                            coroutineScope.launch {
                                tooltipState.dismiss()
                            }
                        }) {
                            Text(richTooltipActionText)
                        }
                    }
                },
                caretSize = DpSize(32.dp, 16.dp)
            ) {
                Text(richTooltipText)
            }
        },
        state = tooltipState
    ) {
        IconButton(onClick = {
            coroutineScope.launch {
                tooltipState.show()
            }
        }) {
            Icon(
                imageVector = Icons.Filled.Camera,
                contentDescription = "Open camera"
            )
        }
    }
}

Pontos principais sobre o código

  • Um RichToolTip mostra uma dica com um título e uma ação de dispensar.
  • Quando ativada, seja com um toque longo ou passando o cursor sobre o conteúdo ToolTipBox, a dica aparece por cerca de um segundo. Para dispensar essa dica, toque em outro lugar da tela ou use o botão de ação "Dispensar".
  • Quando a ação de dispensar é executada, o sistema inicia uma corrotina para chamar tooltipState.dismiss. Isso verifica se a execução da ação não é bloqueada enquanto a dica é mostrada.
  • onClick = coroutineScope.launch { tooltipState.show() } } inicia uma corrotina para mostrar manualmente a dica usando tooltipState.show.
  • O parâmetro action permite adicionar elementos interativos a uma dica, como um botão.
  • O parâmetro caretSize modifica o tamanho da seta da dica.

Resultado

Este exemplo produz o seguinte:

Dica de várias linhas com o título
Figura 4. Uma dica avançada personalizada com uma ação de dispensar ancorada a um ícone de câmera.

Outros recursos

  • Material Design: Dicas (link em inglês)