Usar gestos de pulso no Wear

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Os gestos de pulso permitem interações rápidas com o app, usando uma mão só, quando não é possível tocar na tela.

Por exemplo, o usuário pode rolar a tela de notificações com uma mão enquanto segura um copo de água com a outra. Entre os exemplos que mostram o uso de gestos de pulso estão:

  • Em um app de corrida, navegar pelas telas verticais que mostram o número de passos, o tempo decorrido e o ritmo atual.
  • Rolar a tela para ver informações sobre o voo e portão ao carregar bagagens pelo aeroporto.
  • Rolar por notícias.

Para analisar os gestos de pulso no seu smartwatch, confira se eles estão ativados em Configurações > Gestos > Gestos de pulso. Em seguida, veja o tutorial sobre gestos no smartwatch (Configurações > Gestos > Iniciar tutorial).

O gesto a seguir aciona a Ajuda do Wear OS e não pode ser usado por apps:

  • Balançar o pulso

Os gestos de pulso podem ser usados das seguintes maneiras:

Cada gesto de pulso é mapeado para uma constante int da classe KeyEvent, conforme mostrado na tabela a seguir:

Gesto Evento de tecla Descrição
Virar o pulso para fora KEYCODE_NAVIGATE_NEXT Esse código de tecla vai para o próximo item.
Virar o pulso para dentro KEYCODE_NAVIGATE_PREVIOUS Esse código de tecla vai para o item anterior.

Usar um layout curvo para compatibilidade com gestos de pulso

A classe WearableRecyclerView inclui um layout em curva para listas e oferece suporte a gestos de pulso automaticamente. Ela tem ações predefinidas para gestos de pulso realizados quando a visualização está em foco. Para ver informações sobre como usar a classe WearableRecyclerView, consulte Criar listas. Veja também as Práticas recomendadas.

Observação: a classe WearableRecyclerView substitui uma classe semelhante, que foi descontinuada na Biblioteca de Suporte de Wearables.

Mesmo que você use uma WearableRecyclerView, recomendamos utilizar constantes da classe KeyEvent. As ações predefinidas podem ser substituídas criando uma subclasse para WearableRecyclerView e implementando o callback onKeyDown() novamente. Esse comportamento pode ser totalmente desativado usando setEnableGestureNavigation(false). Para ver mais informações, consulte também Processar ações do teclado.

Usar eventos de teclas diretamente

Você pode usar eventos de teclas fora de uma WearableRecyclerView para acionar novas ações em resposta a eventos de gesto. É importante ressaltar que esses eventos de gestos:

  • são reconhecidos quando um dispositivo está no modo ativo;
  • são entregues da mesma forma que todos os eventos de teclas.

Mais especificamente, esses eventos são entregues à atividade principal ou à visualização com foco no teclado. Assim como ocorre para outros eventos de tecla, uma classe relacionada à interação do usuário, como uma visualização ou uma atividade, que implementa KeyEvent.Callback, pode detectar eventos relacionados a gestos de pulso. O framework do Android chama a visualização ou atividade em foco quando ocorre um evento de tecla. No caso de gestos, o callback do método onKeyDown() é chamado.

Por exemplo, um app pode modificar ações predefinidas em uma visualização ou atividade (implementando KeyEvent.Callback nos dois casos) da seguinte maneira:

Kotlin

class GesturesActivity : Activity() {

    /* KeyEvent.Callback */
    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        return when (keyCode) {
            KeyEvent.KEYCODE_NAVIGATE_NEXT ->
                // Do something that advances a user View to the next item in an ordered list.
                moveToNextItem()
            KeyEvent.KEYCODE_NAVIGATE_PREVIOUS ->
                // Do something that advances a user View to the previous item in an ordered list.
                moveToPreviousItem()
            else -> {
                // If you did not handle it, let it be handled by the next possible element as deemed
                // by the Activity.
                super.onKeyDown(keyCode, event)
            }
        }
    }

    /** Shows the next item in the custom list.  */
    private fun moveToNextItem(): Boolean {
        …
        // Return true if handled successfully, otherwise return false.
        return false
    }

    /** Shows the previous item in the custom list.  */
    private fun moveToPreviousItem(): Boolean {
        …
        // Return true if handled successfully, otherwise return false.
        return false
    }
}

Java

public final class GesturesActivity extends Activity {

 @Override /* KeyEvent.Callback */
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  switch (keyCode) {
   case KeyEvent.KEYCODE_NAVIGATE_NEXT:
    // Do something that advances a user View to the next item in an ordered list.
    return moveToNextItem();
   case KeyEvent.KEYCODE_NAVIGATE_PREVIOUS:
    // Do something that advances a user View to the previous item in an ordered list.
    return moveToPreviousItem();
  }
  // If you did not handle it, let it be handled by the next possible element as deemed by the Activity.
  return super.onKeyDown(keyCode, event);
 }

 /** Shows the next item in the custom list. */
 private boolean moveToNextItem() {
  boolean handled = false;
  …
  // Return true if handled successfully, otherwise return false.
  return handled;
 }

 /** Shows the previous item in the custom list. */
 private boolean moveToPreviousItem() {
  boolean handled = false;
  …
  // Return true if handled successfully, otherwise return false.
  return handled;
 }
}

Práticas recomendadas

  • Revise as páginas KeyEvent e KeyEvent.Callback para ver como funciona a entrega de eventos de teclas para a visualização e a atividade.
  • Mantenha uma adequação direcional consistente:
    • Use "Virar o pulso para fora" para avançar e. "Virar o pulso para dentro" para voltar
  • Tenha um toque paralelo para um gesto.
  • Forneça feedback visual.
  • Não use um código de tecla para implementar funcionalidades que não sejam intuitivas para o resto do sistema. Por exemplo, não use KEYCODE_NAVIGATE_NEXT para cancelar uma ação ou navegar de um lado para o outro com movimentos de pulso.
  • Não intercepte os eventos de tecla em elementos que não façam parte da interface do usuário, por exemplo, visualizações fora da tela ou parcialmente cobertas. Isso é o mesmo que qualquer outro evento de tecla.
  • Não reinterprete gestos de movimento repetidos no seu próprio novo gesto. Isso pode entrar em conflito com o gesto "Balançar o pulso" do sistema.
  • Para que uma visualização receba eventos de tecla de gestos, ela precisa estar em foco. Consulte View::setFocusable(). Como os gestos são tratados como eventos de tecla, eles acionam uma transição que sai do "Modo de toque" e, por isso, podem iniciar ações inesperados. Por esse motivo, como os usuários podem alternar entre o uso de toque e gestos, pode ser necessário usar o método View::setFocusableInTouchmode(). Em alguns casos, também pode ser necessário usar setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS) para que, quando o foco mudar depois de uma modificação ou ao sair do "Modo de toque", a visualização volte para o foco.
  • Use requestFocus() e clearFocus() com cuidado:
    • Ao chamar requestFocus(), verifique se a visualização realmente precisa estar em foco. Se a visualização estiver fora da tela ou coberta por outra, podem ocorrer surpresas quando os gestos acionarem os callbacks.
    • O clearFocus() inicia uma pesquisa de foco para encontrar outra visualização adequada. Dependendo da hierarquia da visualização, essa pesquisa pode exigir um nível de programação mais avançado. Ela também pode acabar atribuindo foco a uma visualização inesperada.
  • Os eventos de tecla são exibidos primeiro na visualização em foco na hierarquia. Se a visualização em foco não processar o evento (ou seja, retornar false), ele não será entregue à visualização mãe, mesmo que o evento possa receber foco e tenha um KeyListener. Em vez disso, ele será entregue à atividade atual, mantendo a hierarquia de visualização em foco. Assim, pode ser necessário capturar todos os eventos no nível superior e, em seguida, transmitir os códigos relevantes. Como alternativa, você pode criar uma subclasse para a atividade e modificar o método dispatchKeyEvent(KeyEvent event), para garantir que as teclas sejam interceptadas quando necessário ou que os eventos de tecla sejam processados quando isso não ocorrer em níveis inferiores.