Entrada por seletor giratório

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

Alguns dispositivos Wear OS têm um botão lateral giratório. Quando o usuário gira o botão, a visualização do app precisa rolar para cima ou para baixo. Esse tipo de entrada é chamada de entrada por seletor giratório.

Muitos contêineres roláveis, como ScrollView, ListView, HorizontalScrollView e WearableRecyclerView, oferecem suporte à entrada por seletor giratório sem exigir nenhum código específico do Wear OS, desde que eles estejam em foco. Estar em foco é um pré-requisito importante porque, no Android 9 (API de nível 28) e versões mais recentes, as visualizações não recebem foco de maneira implícita.

Práticas recomendadas de foco

Para responder a eventos de entrada por seletor giratório, um contêiner rolável precisa estar em foco. Veja a seguir as práticas recomendadas para responder a eventos de entrada por seletor giratório:

  • Por padrão, iniciar uma atividade ou até mesmo tocar em uma visualização não a coloca em foco, mesmo que seja focalizável. Para que a visualização entre em foco, ela precisa usar a tag <requestFocus /> ou chamar View.requestFocus() manualmente.
  • Marque as visualizações roláveis personalizadas como focalizáveis usando android:focusable="true" e android:focusableInTouchMode="true".
  • Os eventos de entrada por seletor giratório são enviados apenas para a visualização em foco. Esses eventos não aparecem na hierarquia de visualização. Se não houver uma visualização em foco ou se ela retornar false de View.onGenericMotionEvent(), o evento é enviado para Activity.onGenericMotionEvent().
  • Se a visualização rolável for anexada depois de Activity.onCreate() (por exemplo, se você esperar que uma solicitação de rede seja concluída antes de criar a IU), chame requestFocus() depois de anexá-la.
  • Se a visualização rolável inicialmente for INVISIBLE ou GONE, você precisará chamar requestFocus() quando definir como VISIBLE.
  • Caso a atividade contenha várias visualizações roláveis, escolha uma para focalizar usando a tag <requestFocus />. O botão lateral giratório não oferece suporte à rolagem aninhada.
  • Caso a IU tenha outra visualização que roube o foco quando o usuário interagir com ela (como InputText), forneça uma maneira de restaurar o foco para a visualização rolável, se necessário. Geralmente, para fazer isso, o app detecta os toques na visualização rolável e chama requestFocus() em resposta.

Comportamento de rolagem personalizado

Caso a visualização rolável não ofereça suporte nativo à rolagem de entrada por seletor giratório ou caso você queira usar essa entrada para fazer algo diferente de rolagem (como aumentar/diminuir o zoom ou girar discos), você pode processar os eventos de rolagem. É importante garantir que a visualização receba foco, caso contrário, os eventos não serão transmitidos.

O snippet de código a seguir mostra como usar MotionEvent, InputDeviceCompat e ViewConfigurationCompat para adicionar rolagem personalizada à visualização:

Kotlin

myView.setOnGenericMotionListener { v, ev ->
  if (ev.action == MotionEvent.ACTION_SCROLL &&
      ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)
  ) {
    // Don't forget the negation here
    val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) *
        ViewConfigurationCompat.getScaledVerticalScrollFactor(
             ViewConfiguration.get(context), context
        )
    // Swap these axes to scroll horizontally instead
    v.scrollBy(0, delta.roundToInt())
    true
  } else {
    false
  }
}

Java

myView.setOnGenericMotionListener(new View.OnGenericMotionListener() {
  @Override
  public boolean onGenericMotion(View v, MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_SCROLL &&
        ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)
    ) {
      // Don't forget the negation here
      float delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) *
          ViewConfigurationCompat.getScaledVerticalScrollFactor(
               ViewConfiguration.get(context), context
          );

      // Swap these axes to scroll horizontally instead
      v.scrollBy(0, Math.round(delta));

      return true;
    }
    return false;
  }
});

Testar usando um emulador

Use o Android Emulator para simular a rolagem de entrada por seletor giratório em um dispositivo Wear. Inicie o app Wear no emulador ao executar seu projeto ou arraste um arquivo APK para o emulador para instalá-lo.

Para testar a entrada por seletor giratório no emulador:

  1. No SDK Manager, use a guia SDK Tools para instalar o Android Emulator 26.0.3 ou versões mais recentes.
  2. No Studio, selecione Tools > Android > AVD Manager. Crie um novo dispositivo Wear com API de nível 25 ou mais recente.
  3. Execute o emulador no Android Studio.
  4. Clique no botão flutuante (três pontos na parte de baixo da barra de ferramentas do emulador). Clique na guia Rotary input na nova janela para abrir a interface de entrada por seletor giratório e tente rolar o seletor.

O vídeo a seguir mostra a entrada por seletor giratório no emulador: