Uma stylus pode ser uma ferramenta excepcionalmente produtiva e criativa. No entanto, quando os usuários desenham, escrevem ou interagem com um app usando uma stylus, às vezes eles tocam na tela com a palma da mão. O evento de toque pode ser informado ao app antes que o sistema reconheça e desconsidere o evento como um toque acidental da palma da mão.
Práticas recomendadas
O app precisa identificar e ignorar eventos de toque irrelevantes. No Jetpack
Compose, é possível acessar o MotionEvent do Android de um
PointerEvent. Verifique o MotionEvent para ACTION_CANCEL, que
indica que um gesto precisa ser interrompido e pode precisar ser revertido. No
Android 13 (nível 33 da API) e versões mais recentes, verifique a flag FLAG_CANCELED
nos eventos ACTION_CANCEL e ACTION_POINTER_UP, que fornece um
forte sinal de que o toque não foi intencional, como um toque de palma da mão.
Ingredientes
Modifier.pointerInput(): o modificador do Compose usado para processar a entrada de ponteiro.PointerEvent: representa um evento de ponteiro no Compose, que contém uma ou mais mudanças.PointerEvent.motionEvent: propriedade de extensão que fornece acesso aoMotionEventdo Android subjacente (aceita valores nulos).MotionEvent: representa eventos de toque e movimento. Contém as informações necessárias para determinar se um evento será desconsiderado ou não.ACTION_CANCEL: constanteMotionEventque indica que um gesto foi cancelado. Ele precisa ser interrompido e pode precisar ser revertido.ACTION_POINTER_UP: constanteMotionEventque indica que um ponteiro diferente do primeiro foi levantado, ou seja, parou de fazer contato com a tela do dispositivo.FLAG_CANCELED: constanteMotionEventque indica que o ponteiro que foi levantado causou um evento de toque não intencional. Adicionado aos eventosACTION_POINTER_UPeACTION_CANCELno Android 13 (nível 33 da API) e mais recentes.
Etapas
Examine objetos MotionEvent enviados para seu app. Use as APIs MotionEvent
para determinar as características do evento:
- Eventos de ponteiro único: procure
ACTION_CANCEL, que indica que o gesto precisa parar. No Android 13 e mais recentes, procure também porFLAG_CANCELEDpara confirmar se o toque foi acidental. - Eventos com vários ponteiros: no Android 13 e mais recentes, procure
ACTION_POINTER_UPeFLAG_CANCELEDpara identificar toques não intencionais.
Responda a esses eventos interrompendo o gesto e revertendo as mudanças temporárias.
1. Obter objetos de eventos de movimento
Use Modifier.pointerInput para processar a entrada de ponteiro em um elemento combinável. No escopo de entrada de ponteiro, use awaitPointerEventScope e awaitPointerEvent para receber eventos e recupere o MotionEvent do Android usando a propriedade motionEvent:
import androidx.compose.ui.input.pointer.pointerInput Box( modifier = Modifier .fillMaxSize() .pointerInput(Unit) { awaitPointerEventScope { while (true) { val event = awaitPointerEvent() val motionEvent = event.motionEvent if (motionEvent != null) { // Process motion event. } } } } )
2. Determinar a ação e as flags do evento
Verifique o MotionEvent de ACTION_CANCEL, que indica um evento de ponteiro único
em todos os níveis de API. No Android 13 e mais recentes, procure ACTION_POINTER_UP
em FLAG_CANCELED:
import androidx.compose.ui.input.pointer.pointerInput Box( modifier = Modifier .fillMaxSize() .pointerInput(Unit) { awaitPointerEventScope { while (true) { val event = awaitPointerEvent() val motionEvent = event.motionEvent ?: continue when (motionEvent.actionMasked) { MotionEvent.ACTION_CANCEL -> { // Process canceled single-pointer motion event for all SDK versions. } MotionEvent.ACTION_POINTER_UP -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && (motionEvent.flags and MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED ) { // Process canceled multi-pointer motion event for Android 13 and higher. } } } } } } )
3. Desfazer o gesto
Depois de identificar um toque da palma da mão, você pode desfazer os efeitos do gesto na tela.
O app precisa manter um histórico de ações do usuário para que entradas não intencionais, como toques da palma da mão, possam ser desfeitas. Consulte Implementar um app de desenho básico no codelab Melhorar o suporte à stylus em um app Android para conferir um exemplo.
Resultados
O app agora pode identificar e rejeitar toques da palma da mão em eventos de vários ponteiros no Android 13 e níveis da API mais recentes e em eventos de ponteiro único em todos os níveis da API.
Outros recursos
Para mais informações, consulte os tópicos abaixo:
- Recursos e APIs do Android 13: Rejeição da palma aprimorada
- Guias para desenvolvedores
- Recursos avançados da stylus
- Seção Rejeição da palma da mão em Compatibilidade de entrada em telas grandes
- Codelab: Melhorar o suporte à stylus em um app Android