The Android Developer Challenge is back! Submit your idea before December 2.

Usar gestos de pulso no Wear

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, um usuário pode percorrer as 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.
  • No aeroporto com bagagem, percorrer as informações de voo e portão.
  • Rolar por notícias.

Para analisar os gestos de pulso no seu smartwatch, confirme que eles estão ativados selecionando Configurações > Gestos > Gestos de pulso ativados. Em seguida, conclua o tutorial sobre gestos no smartwatch (Configurações > Gestos > Iniciar tutorial).

O gesto a seguir da Ajuda do Wear OS não está disponível para 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 oferece um layout curvo para listas e é compatível automaticamente com gestos de pulso. A classe tem ações predefinidas para ocorrências de gestos de pulso quando a visualização está em foco. Para mais informações sobre como usar a classe WearableRecyclerView, consulte Criar listas. Consulte também Práticas recomendadas.

Observação: a classe WearableRecyclerView substitui uma classe obsoleta semelhante na Biblioteca de Suporte de Wearables.

Mesmo que você use uma WearableRecyclerView, convém usar constantes da classe KeyEvent. As ações predefinidas podem ser modificadas subclassificando a WearableRecyclerView e implementando novamente o callback onKeyDown(). O comportamento pode ser desativado totalmente usando setEnableGestureNavigation(false). Consulte também Como gerenciar as 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 gestos. É 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.

Especificamente, esses eventos são entregues à atividade principal, à visualização com o foco do teclado. Assim como qualquer outro evento de tecla, uma classe relacionada à interação do usuário (como uma visualização ou atividade) que implementa KeyEvent.Callback pode ouvir eventos de teclas relacionados a gestos de pulso. A estrutura do Android chama a visualização ou atividade que tem o foco com os eventos de teclas. Para gestos, o callback do método onKeyDown() é chamado quando ocorrem gestos.

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

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 do KeyEvent e do KeyEvent.Callback para a entrega de eventos de teclas para sua visualização e 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 no eixo esquerdo-direito com movimentos.
  • Não intercepte os eventos de teclas em elementos que não façam parte da interface do usuário, por exemplo, as visualizações que estão 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 gesto, ela precisa estar em foco. Consulte View::setFocusable (). Como os gestos são tratados como eventos de tecla, eles acionam uma transição para fora do "Modo de toque", o que pode fazer coisas inesperadas. Portanto, como os usuários podem alternar entre o uso de toque e gestos, o método View :: setFocusableInTouchmode () pode ser necessário. Em alguns casos, também pode ser necessário usar setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS) para que, quando o foco mudar depois de uma alteração no "Modo de toque", a visualização receba o foco.
  • Use requestFocus() e clearFocus() com cuidado:
    • Ao chamar requestFocus(), verifique se a visualização realmente precisa ter o foco. Se a visualização estiver fora da tela ou for coberta por outra, surpresas poderão ocorrer quando os gestos acionarem callbacks.
    • O clearFocus() inicia uma pesquisa de foco para encontrar outra visualização adequada. Dependendo da hierarquia da visualização, essa pesquisa pode exigir computação não trivial. Ela também pode acabar atribuindo foco a uma visualização que você não espera que receba foco.
  • Os eventos de teclas são exibidos primeiro na visualização com foco na hierarquia "View". Se a visualização focalizada não gerenciar o evento (ou seja, retornar false), o evento não será entregue para a visualização pai, mesmo que possa receber foco e tenha um KeyListener. Em vez disso, o evento será entregue à atividade atual, mantendo a hierarquia de visualização com foco. Assim, pode ser necessário capturar todos os eventos no nível superior e, em seguida, passar os códigos relevantes para baixo. Como alternativa, você pode criar a subclasse atividade e substituir o método dispatchKeyEvent(KeyEvent event) para garantir que as teclas sejam interceptadas quando necessário ou manipuladas quando não tratadas em camadas inferiores.