Sair de atividades em tela cheia no Wear

Os usuários podem sair de uma atividade do Wear OS deslizando da esquerda para a direita. Se o app tiver rolagem horizontal, os usuários sairão dele navegando até a borda do conteúdo e, em seguida, deslizando da esquerda para a direita. Ao pressionar o botão liga/desliga, os usuários voltarão para o mostrador do relógio.

Gesto de deslizar para dispensar

Os usuários deslizam da esquerda para a direita para fechar a tela atual. Portanto, recomendamos que você use o seguinte:

  • Layouts verticais
  • Contêineres de conteúdo

Recomendamos também que seu app não contenha gestos de deslizar horizontalmente.

Dispensar uma atividade

Atividades suportam automaticamente deslizar para dispensar. Deslizar uma atividade da esquerda para a direita faz com que ela seja dispensada, e o app navegará para a backstack.

Dispensar um fragmento

Para oferecer suporte ao gesto de deslizar para dispensar em fragmentos, você precisa unir a visualização que contém o fragmento na classe SwipeDismissFrameLayout. Considere isso ao decidir usar ou não fragmentos. Use a classe SwipeDismissFrameLayout conforme mostrado no exemplo abaixo:

Kotlin

class SwipeDismissFragment : Fragment() {
    private val callback = object : SwipeDismissFrameLayout.Callback() {
        override fun onSwipeStarted(layout: SwipeDismissFrameLayout) {
            // Optional
        }

        override fun onSwipeCanceled(layout: SwipeDismissFrameLayout) {
            // Optional
        }

        override fun onDismissed(layout: SwipeDismissFrameLayout) {
            // Code here for custom behavior, such as going up the
            // back stack and destroying the fragment but staying in the app.
        }
    }

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View =
            SwipeDismissFrameLayout(activity).apply {

                // If the fragment should fill the screen (optional), then in the layout file,
                // in the androidx.wear.widget.SwipeDismissFrameLayout element,
                // set the android:layout_width and android:layout_height attributes
                // to "match_parent".

                inflater.inflate(
                        R.layout.swipe_dismiss_frame_layout,
                        this,
                        false
                ).also { inflatedView ->
                    addView(inflatedView)
                }
                addCallback(callback)
            }
}

Java

public class SwipeDismissFragment extends Fragment {
  private final Callback callback =
    new Callback() {
      @Override
        public void onSwipeStart() {
          // Optional
        }

        @Override
        public void onSwipeCancelled() {
          // Optional
        }

        @Override
        public void onDismissed(SwipeDismissFrameLayout layout) {
          // Code here for custom behavior, such as going up the
          // back stack and destroying the fragment but staying in the app.
        }
      };

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    SwipeDismissFrameLayout swipeLayout = new SwipeDismissFrameLayout(getActivity());

    // If the fragment should fill the screen (optional), then in the layout file,
    // in the androidx.wear.widget.SwipeDismissFrameLayout element,
    // set the android:layout_width and android:layout_height attributes
    // to "match_parent".

    View inflatedView = inflater.inflate(R.layout.swipe_dismiss_frame_layout, swipeLayout, false);
    swipeLayout.addView(inflatedView);
    swipeLayout.addCallback(callback);

    return swipeLayout;
    }
}

Observação: ao usar fragmentos na sua atividade, use FragmentManager.add em vez de FragmentManager.replace para oferecer suporte ao gesto de deslizar para dispensar. Isso garante que seu fragmento anterior renderize no fragmento da camada superior enquanto é dispensado.

Visualizações roláveis horizontais

Em alguns casos, como em uma visualização contendo um mapa que oferece suporte ao movimento panorâmico, a interface do usuário não impede o deslizamento horizontal. Nessa situação, há duas opções:

  • Se a backstack for curta, o usuário poderá dispensar o app e retornar à tela inicial do mostrador do relógio pressionando o botão liga/desliga.
  • Se você quiser que o usuário vá para a backstack, envolva a visualização em um objeto SwipeDismissFrameLayout, que ofereça suporte ao deslizamento de borda. O deslizamento de borda é ativado quando a visualização ou as filhas dela retornam true de uma chamada canScrollHorizontally(). O deslizamento de borda permite que o usuário dispense a visualização deslizando a partir de 10% do lado mais à esquerda da tela, em vez de em qualquer lugar da visualização.

Os exemplos abaixo mostram como envolver uma visualização em um objeto SwipeDismissFrameLayout:

<androidx.wear.widget.SwipeDismissFrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/swipe_dismiss_root" >

    <TextView
        android:id="@+id/test_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="Swipe me to dismiss me." />
</androidx.wear.widget.SwipeDismissFrameLayout>

Kotlin

activity?.findViewById<SwipeDismissFrameLayout>(R.id.swipe_dismiss_root)?.apply {
    addCallback(object : SwipeDismissFrameLayout.Callback() {

        override fun onDismissed(layout: SwipeDismissFrameLayout) {
            layout.visibility = View.GONE
        }
    })
}

Java

SwipeDismissFrameLayout testLayout =
    (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
testLayout.addCallback(new SwipeDismissFrameLayout.Callback() {
    @Override
    public void onDismissed(SwipeDismissFrameLayout layout) {
        layout.setVisibility(View.GONE);
    }
  }
);

Não recomendado: desativar o gesto de deslizar para dispensar

Geralmente, não é recomendado desativar o gesto de deslizar para dispensar, porque o usuário espera dispensar qualquer tela ao deslizar. Em um caso excepcional, você pode ampliar o tema padrão em um recurso de estilo e definir o atributo android:windowSwipeToDismiss como false, conforme mostrado no exemplo de código abaixo:

<resources>
  <style name="AppTheme" parent="@android:style/Theme.DeviceDefault">
    <item name="android:windowSwipeToDismiss">false</item>
  </style>
</resources>

Você pode informar aos usuários no primeiro uso do app que eles podem sair do app pressionando o botão liga/desliga.

Dispensar com o botão liga/desliga

Pressionar o botão liga/desliga físico envia um evento da tecla liga/desliga. Portanto, não é possível usar o botão liga/desliga como botão "Voltar" ou para a navegação em geral.

Quando pressionado, o botão liga/desliga retorna o usuário para a tela inicial do mostrador do relógio. Há duas exceções:

  • Se o usuário estiver em um Editor de método de entrada (IME), por exemplo, uma tela de reconhecimento de escrita manual, e pressionar o botão, o IME será fechado e o usuário será levado de volta ao app.
  • Se o usuário estiver no mostrador do relógio, pressionar o botão físico abrirá o Acesso rápido aos apps.

Observação: quando o botão liga/desliga é pressionado, o método isFinishing() da classe Activity não retorna true e também não é possível interceptar o evento de tecla.

Para mais informações, consulte Navegação.