Zamknij pełny ekran na Wear

Wypróbuj tworzenie wiadomości
Jetpack Compose na Wear OS to zalecany pakiet narzędzi do tworzenia interfejsu na Wear OS.

Użytkownik może zamknąć aktywność na Wear OS, przesuwając palcem od lewej do prawej. Jeśli aplikacja ma przewijanie poziome, użytkownik może ją zamknąć, przechodząc do krawędzi treści i przesuwając palcem od lewej do prawej. Naciśnięcie przycisku zasilania powoduje również powrót do tarczy zegarka.

Gest przesunięcia, aby zamknąć

Użytkownicy przesuwają palcem z lewej do prawej, aby zamknąć bieżący ekran. Dlatego zalecamy użycie tych opcji:

  • Układy pionowe
  • Kontenery treści

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

Zamknij aktywność

Aktywności automatycznie obsługują gest przesunięcia w stronę, aby zamknąć. Przesunięcie aktywności z lewej do prawej powoduje jej zamknięcie, a aplikacja przechodzi do poprzedniego stosu.

Zamknij fragment

Aby umożliwić usuwanie fragmentów przez przesunięcie, musisz umieścić widok zawierający fragmenty w klasie SwipeDismissFrameLayout. Weź to pod uwagę, decydując, czy używać fragmentów. Użyj klasy SwipeDismissFrameLayout, jak w tym przykładzie:

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: gdy używasz fragmentów w ramach aktywności, użyj FragmentManager.add zamiast FragmentManager.replace, aby umożliwić gest przesunięcia w stronę, aby zamknąć. Dzięki temu poprzedni fragment będzie renderowany pod górnym fragmentem, gdy ten ostatni zostanie przesunięty.

Widoki przewijane poziomo

W niektórych przypadkach, np. w widoku zawierającym mapę, która obsługuje przesuwanie, interfejs użytkownika nie może uniemożliwić przesuwania poziomego. W tym scenariuszu masz 2 opcje:

  • Jeśli stos 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, aby użytkownik przeszedł do poprzedniego elementu w steku, możesz opakować widok w obiekcie SwipeDismissFrameLayout, który obsługuje przesuwanie palcem po krawędzi ekranu. Przesuwanie krawędzi jest włączone, gdy widok lub jego elementy podrzędne zwracajątrue z poziomu canScrollHorizontally() wywołania. Przesunięcie palcem po krawędzi ekranu pozwala użytkownikowi zamknąć widok przez przesunięcie palcem po lewej krawędzi ekranu (nie w dowolnym miejscu widoku).

Z tych przykładów dowiesz się, jak opakować 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łączenie funkcji przesuwania w celu zamknięcia

Nie zalecamy wyłączania funkcji usuwania przez przesunięcie, ponieważ użytkownik spodziewa się, że może usunąć dowolny ekran przez przesunięcie. W wyjątkowych przypadkach możesz rozszerzyć domyślny motyw w  zasobie stylów i ustawić atrybut android:windowSwipeToDismiss na false, jak pokazano w tym przykładzie kodu:

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

Możesz wtedy poinformować użytkowników, że mogą zamknąć aplikację, naciskając przycisk zasilania.

Zamknij przyciskiem zasilania

Naciśnięcie fizycznego przycisku zasilania powoduje wysłanie zdarzenia power_key. Nie można więc używać przycisku zasilania jako przycisku Wstecz ani do nawigacji.

Po naciśnięciu przycisku zasilania użytkownik wraca do ekranu głównego tarczy zegarka. Istnieją dwa wyjątki:

  • Jeśli użytkownik korzysta z edytora metody wprowadzania (IME), np. ekranu rozpoznawania pisma odręcznego, naciśnięcie przycisku spowoduje zamknięcie IME i powrót do aplikacji.
  • Jeśli użytkownik jest na tarczy zegarka, naciśnięcie przycisku sprzętowego powoduje otwarcie menu z aplikacjami.

Uwaga: gdy naciśniesz przycisk zasilania, metoda isFinishing() klasy Activity nie zwraca wartości true i nie możesz przechwycić kluczowego zdarzenia.

Więcej informacji znajdziesz w artykule Nawigacja.