Saber quando um elemento da interface está visível na tela é útil para vários casos de uso, como análise de dados de registros, gerenciamento do estado da interface e otimização de recursos com a reprodução ou pausa automática de conteúdo de vídeo. O Compose oferece vários modificadores para rastrear a visibilidade de elementos da interface, como:
onVisibilityChanged: esse modificador notifica você quando a visibilidade de um elemento combinável muda. É ideal para acionar uma ação ou um efeito colateral sempre que o elemento combinável ficar visível.onLayoutRectChanged: esse modificador fornece informações sobre os limites de um elemento combinável em relação à raiz, à janela e à tela. Ela oferece controle de baixo nível e é a API de base paraonVisibilityChanged. O modificador é semelhante aonGloballyPositioned, mas oferece melhor desempenho e maior flexibilidade.
É possível usar essas APIs com qualquer elemento combinável como parte da cadeia de modificadores.
Monitorar mudanças de visibilidade com onVisibilityChanged
Saber quando um item está visível ou parcialmente visível para um usuário pode ajudar a acompanhar a análise de dados (por exemplo, contagem de visualizações), otimizar o desempenho (buscando ou pré-buscando dados da rede somente quando o item está visível) ou até mesmo acionar eventos (reproduzir ou pausar vídeos).
Para receber uma notificação quando a visibilidade de um item mudar, use o
modificador onVisibilityChanged, como mostrado no exemplo a seguir:
Text( text = "Some text", modifier = Modifier .onVisibilityChanged { visible -> if (visible) { // Do something if visible. } else { // Do something if not visible. } } .padding(vertical = 8.dp) )
O modificador onVisibilityChanged fornece um valor booleano que reflete o
estado de visibilidade atual do elemento combinável. Além disso, ele oferece
parâmetros como minFractionVisible e minDurationMs, que dão
mais controle sobre quando o callback de visibilidade precisa ser acionado.
Como em qualquer outro modificador, a sequência é importante com o modificador
onVisibilityChanged. O exemplo anterior mostra uma função combinável que renderiza texto
com padding. Para garantir que o modificador afete todo o elemento combinável,
incluindo o padding, adicione o modificador onVisibilityChanged antes do
padding.
Definir um limite de tempo em um elemento combinável antes de acionar o callback de visibilidade
Em algumas situações, talvez você queira acionar uma ação somente depois que um item estiver visível para o usuário por um determinado período. Por exemplo, é possível reproduzir automaticamente um vídeo se ele estiver visível para o usuário há algum tempo.
Para acionar uma ação depois que um item ficar visível por um período definido, use o
parâmetro minDurationMs no modificador onVisibilityChanged. Esse parâmetro
especifica o tempo mínimo que um elemento combinável precisa ficar continuamente
visível para que o callback seja acionado. Se o elemento combinável deixar de ficar visível
antes que a duração seja atingida, o timer será redefinido. O valor padrão é 0
milissegundo.
O snippet abaixo muda o plano de fundo para roxo depois que o elemento de composição fica visível para o usuário por três segundos:
var background by remember { mutableStateOf(PalePink) } Card( modifier = modifier // ... .onVisibilityChanged(minDurationMs = 3000) { if (it) { background = MutedPlum } } ) { Box( modifier = Modifier // ... .background(background), contentAlignment = Alignment.Center, ) { // ... } }
Definir uma fração visível mínima
Definir uma fração mínima visível para o callback de visibilidade do elemento combinável é
útil ao trabalhar com conteúdo rolável (por exemplo, LazyColumn) para
otimizar a busca de dados de itens que excedem o tamanho da tela.
Nesses casos, use o parâmetro minFractionVisible no modificador
onVisibilityChanged para definir a fração que precisa estar na tela
para que o elemento combinável seja marcado como visível.
Ele aceita valores flutuantes de 0.0f a 1.0f e é definido como 1.0f por
padrão. 1.0f significa que o elemento combinável precisa estar completamente visível na tela
ou preencher toda a janela de visualização, se for maior que ela.
O callback recebe true quando a fração visível é maior que
minFractionVisible ou quando o elemento combinável está completamente visível ou preenche a
janela de visualização. Caso contrário, ele recebe false.
LazyColumn( modifier = modifier.fillMaxSize() ) { item { Box( modifier = Modifier // ... // Here `visible` is `true` when more than 20% of the composable is visible. .onVisibilityChanged( minFractionVisible = 0.2f, ) { visible -> if (visible) { // Call specific logic here. // viewModel.fetchDataFromNetwork() } } .padding(vertical = 16.dp) ) { Text( text = "Sample Text", modifier = Modifier.padding(horizontal = 16.dp) ) } } }
Figura 2. Sem que minFractionVisible seja definido.
|
Figura 3. Com minFractionVisible definido como 0.2f.
|
O exemplo usado anteriormente pré-carrega os Androidify Bots da rede antes
que o elemento combinável fique totalmente visível. Na Figura 2, o terceiro bot não é carregado,
porque o elemento combinável não está totalmente visível. Na Figura 3, minFractionVisible está
definido, e o terceiro bot é carregado antes de ficar totalmente visível na tela.
Ocultar um elemento combinável e manter o espaço dele
Para ocultar um elemento combinável sem mudar o layout ao redor, use o
modificador visible. Quando você transmite false, o elemento de composição ainda é medido,
mas não é posicionado nem desenhado. Ao contrário de definir alpha como 0f, visible(false)
também remove o elemento da árvore de acessibilidade e desativa as interações
por toque, preservando o espaço de layout.
O exemplo a seguir mostra um ícone de marca de seleção que mantém o espaço enquanto está oculto, para que o texto ao lado dele não se mova:
Row(modifier, verticalAlignment = Alignment.CenterVertically) { Icon( painter = painterResource(R.drawable.check), contentDescription = "Saved", modifier = Modifier // The icon keeps its space while it's hidden, so the text doesn't move. .visible(isSaved) ) Text("Draft", Modifier.padding(start = 8.dp)) }
Use visible quando o layout ao redor do elemento combinável não puder se mover conforme o
elemento aparece e desaparece. Para remover o elemento que pode ser composto e o espaço dele,
não o chame ou use AnimatedVisibility para animar a entrada e a saída.