Zamknij pełny ekran na Wear

Użytkownik może zakończyć aktywność w Wear OS, przesuwając palcem od lewej do prawej. Jeśli aplikacja ma przewijanie w poziomie, użytkownik zamyka ją, przechodząc do krawędzi treści, a następnie przesuwając palcem od lewej do prawej. Naciśnięcie przycisku zasilania powoduje też powrót do tarczy zegarka.

Gest przesuwania, aby zamknąć

Użytkownicy przesuwają palcem od lewej do prawej, aby zamknąć bieżący ekran. Dlatego zalecamy korzystanie z:

  • Układy pionowe
  • Kontenery treści

Zalecamy też, by aplikacja nie zawierała gestów przesuwania w poziomie.

Odrzucanie aktywności

Aktywności automatycznie obsługują przesuwanie, aby zamknąć. Przesunięcie działania z lewej do prawej powoduje jego odrzucenie i przejście w dół stosu wstecznego.

Odrzuć fragment

Aby obsługiwać funkcję przesuwania, aby zamknąć fragmenty, musisz opakować widok zawierający fragment do klasy SwipeDismissFrameLayout. Weź to pod uwagę przy podejmowaniu decyzji o użyciu fragmentów. Użyj klasy SwipeDismissFrameLayout zgodnie z tym przykładem:

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

Uwaga: jeśli w aktywności używasz fragmentów, do obsługi gestu przesuwania palcem używaj FragmentManager.add, a nie FragmentManager.replace. Dzięki temu poprzedni fragment będzie renderowany pod górnym fragmentem podczas jego przesunięcia.

Widoki z możliwością przewijania w poziomie

W niektórych przypadkach, np. w widoku zawierającym mapę, która obsługuje przesuwanie, interfejs użytkownika nie może zapobiec przesuwaniu w poziomie. W takiej sytuacji masz 2 możliwości:

  • Jeśli stos wsteczny jest krótki, użytkownik może zamknąć aplikację i wrócić do ekranu głównego tarczy zegarka, naciskając przycisk zasilania.
  • Jeśli chcesz, by użytkownik zszedł na dół stosu, możesz owinąć widok w obiekcie SwipeDismissFrameLayout, który obsługuje przesuwanie od krawędzi. Przesunięcie po krawędzi jest włączone, gdy widok lub jego elementy podrzędne zwracają właściwość true z wywołania canScrollHorizontally(). Przesuwanie po krawędzi umożliwia użytkownikowi zamknięcie widoku przez przesunięcie od 10% ekranu znajdującego się najdalej po lewej, a nie w dowolnym miejscu.

Poniższe przykłady pokazują, jak spakować widok w obiekcie 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);
    }
  }
);

Niezalecane: wyłącz funkcję przesuwania, aby zamknąć

Zasadniczo nie zalecamy wyłączania funkcji przesuwania, aby zamknąć, ponieważ użytkownik oczekuje, że użytkownik zamknie każdy ekran jednym ruchem przesunięcia. W wyjątkowych przypadkach możesz rozszerzyć domyślny motyw w zasobie stylu i ustawić atrybut android:windowSwipeToDismiss na false, jak pokazano w tym przykładowym kodzie:

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

Następnie możesz poinformować użytkowników, że przy pierwszym użyciu Twojej aplikacji mogą ją zamknąć, naciskając przycisk zasilania.

Zamknij przyciskiem zasilania

Naciśnięcie fizycznego przycisku zasilania wysyła zdarzenie klawisza zasilania. Dlatego nie można używać przycisku zasilania jako przycisku Wstecz ani ogólnie do nawigacji.

Po naciśnięciu przycisk zasilania powraca na ekran główny tarczy zegarka. Istnieją dwa wyjątki:

  • Jeśli użytkownik korzysta z edytora metody wprowadzania (IME), na przykład na ekranie rozpoznawania pisma odręcznego, naciśnięcie przycisku zamyka edytor IME i powraca do aplikacji.
  • Jeśli użytkownik znajduje się na tarczy zegarka, naciśnięcie przycisku sprzętowego spowoduje otwarcie programu uruchamiającego aplikacje.

Pamiętaj, że po naciśnięciu przycisku zasilania metoda isFinishing() klasy Activity nie zwraca true i nie możesz przechwycić kluczowego zdarzenia.

Więcej informacji znajdziesz w sekcji Nawigacja.