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

Cómo salir de las actividades de pantalla completa en Wear

Un usuario puede salir de una actividad de Wear OS deslizando el dedo de izquierda a derecha. Si la app tiene desplazamiento horizontal (p. ej., el tipo de desplazamiento disponible en una app que contiene mapas), el usuario podrá salir de ella navegando hasta el borde del contenido y deslizando el dedo de izquierda a derecha.

Si el usuario presiona el botón de encendido, regresará a la cara del reloj.

Consulta los siguientes recursos relacionados:

Gesto de deslizar para descartar

Los usuarios deslizan el dedo de izquierda a derecha para cerrar la pantalla actual. Por lo tanto, se recomienda que utilices lo siguiente:

También se recomienda que tu app no incluya gestos de deslizamiento horizontal.

Cómo descartar una actividad

Una actividad admite automáticamente que el usuario deslice el dedo para descartarla. Al deslizar una actividad de izquierda a derecha, se produce un rechazo, y la app navega hacia la parte posterior de la pila de actividades.

Fragmentos

Puedes envolver una vista que contenga un fragmento en la clase SwipeDismissFrameLayout de la siguiente manera:

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 android.support.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 android.support.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;
        }
    }
    

Nota: La clase SwipeDismissFrameLayout reemplaza una clase similar obsoleta en la Biblioteca de compatibilidad con dispositivos wearables.

Vistas horizontales desplazables

En algunos casos, como en una vista que contiene un mapa que admite el desplazamiento lateral, la interfaz de usuario no evitaría el deslizamiento horizontal. En este escenario, hay dos opciones:

  • Si la pila de actividades es corta, el usuario puede descartar la app y volver a la pantalla principal (la cara del reloj) presionando el botón de encendido.
  • Si deseas que el usuario baje por la pila de actividades, puedes ajustar la vista en un objeto SwipeDismissFrameLayout, que admite el deslizamiento en el borde. Este tipo de desplazamiento se habilita cuando la vista o sus elementos secundarios muestran un valor true de una llamada a canScrollHorizontally(). El deslizamiento en el borde le permite al usuario descartar la vista deslizando el dedo desde el lado izquierdo de la pantalla (actualmente establecido en 10% del ancho de la pantalla) y no solo en cualquier lugar de la vista.

Para envolver una vista en un objeto SwipeDismissFrameLayout, consulta los siguientes ejemplos:

XML para un archivo de diseño

    <android.support.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." />
    </android.support.wear.widget.SwipeDismissFrameLayout>
    

Fragmento de código

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);
        }
      }
    );
    

No recomendado: Inhabilitar la función deslizar para descartar

Por lo general, no se recomienda desactivar la función deslizar para descartar porque el usuario espera descartar cualquier pantalla deslizando el dedo. En un caso excepcional, puedes extender el tema predeterminado (en un recurso de estilo) y establecer el atributo android:windowSwipeToDismiss como false:

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

Luego, puedes informarles a los usuarios (en el primer uso de la app) que pueden salir de ella presionando el botón de encendido.

Comportamiento de la función de descarte antes de Wear 2.0

Antes de Wear 2.0, se usaba la clase DismissOverlayView a fin de implementar la función de mantener presionada la app para descartarla. Ya no se debe usar DismissOverlayView.

Además, ya no se recomienda la función de mantener presionada la app para descartarla. No la implementes para descartar actividades de pantalla completa (actividades panorámicas o inmersivas, como Google Maps).

Función de descarte mediante el botón de encendido

Al presionar el botón de encendido (hardware), se envía un evento de la tecla de encendido. Por lo tanto, no puedes utilizar el botón de encendido como botón de retroceso o para la navegación en general.

Cuando se presiona el botón de encendido, el usuario regresa a la pantalla principal (cara del reloj). Hay dos excepciones:

  • Si el usuario está en un IME (un Editor de métodos de entrada; por ejemplo, una pantalla de reconocimiento de escritura a mano), al presionar el botón, se cierra el IME y el usuario regresa a la app.
  • Si el usuario está en la cara del reloj, al presionar el botón de hardware, se abre el iniciador de apps.

Ten en cuenta que, cuando se presiona el botón de encendido, el método isFinishing() de la clase de Activity no muestra true (ni puede interceptar el evento clave).