Как выйти из полноэкранного режима на устройстве Wear OS

Попробуйте Compose
Jetpack Compose – это рекомендуемый набор инструментов для создания пользовательского интерфейса в Wear OS.

Чтобы выйти из действия Wear OS, проведите по экрану слева направо. Если в приложении есть горизонтальная прокрутка, пользователь выходит из него, переходя к краю контента и проводя пальцем слева направо. Нажатие кнопки питания также возвращает пользователя к циферблату.

Жест смахивания, скрывающий окно

Чтобы закрыть текущий экран, пользователи проводят по нему слева направо. Поэтому мы рекомендуем использовать следующие варианты:

  • Вертикальные макеты
  • Контейнеры контента

Также не рекомендуем использовать в приложении горизонтальные жесты.

Как закрыть действие

Действия автоматически поддерживают жест смахивания для закрытия. Проведя по экрану слева направо, пользователь закрывает текущее действие и переходит к предыдущему в обратном стеке.

Как закрыть фрагмент

Чтобы поддерживать жест смахивания для закрытия во фрагментах, необходимо обернуть представление, содержащее фрагмент, в класс SwipeDismissFrameLayout. Учитывайте это, когда решаете, использовать ли фрагменты. Используйте класс SwipeDismissFrameLayout, как показано в примере ниже.

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

Примечание. Если вы используете фрагменты в действии, используйте FragmentManager.add, а не FragmentManager.replace, чтобы поддерживать жест закрытия смахиванием. Это гарантирует, что предыдущий фрагмент будет отображаться под верхним фрагментом, пока он смахивается.

Горизонтальные прокручиваемые представления

В некоторых случаях, например в представлении с картой, поддерживающей панорамирование, пользовательский интерфейс не может предотвратить горизонтальное пролистывание. В этом случае есть два варианта:

  • Если обратный стек короткий, пользователь может закрыть приложение и вернуться на главный экран циферблата, нажав кнопку питания.
  • Если вы хотите, чтобы пользователь мог перемещаться по обратному стеку, вы можете обернуть представление в объект SwipeDismissFrameLayout, который поддерживает жест пролистывания от края экрана. Пролистывание от края экрана включено, если представление или его дочерние элементы возвращают true из вызова canScrollHorizontally(). В этом случае, чтобы закрыть экран, пользователю нужно провести пальцем по его левому краю (10% ширины экрана), а не по любой его части.

В следующих примерах показано, как упаковать представление в объект 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);
    }
  }
);

Не рекомендуется: отключить закрытие смахиванием

Мы не рекомендуем отключать эту функцию, поскольку пользователи привыкли закрывать экраны жестом смахивания. В исключительных случаях вы можете расширить тему по умолчанию в ресурсе стиля и задать для атрибута android:windowSwipeToDismiss значение false, как показано в примере кода ниже.

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

Затем вы можете сообщить пользователям, что они могут выйти из приложения, нажав кнопку питания.

Отключение с помощью кнопки питания

Нажатие физической кнопки питания отправляет событие кнопки питания. Поэтому вы не можете использовать кнопку питания в качестве кнопки "Назад" или для навигации в целом.

При нажатии кнопки питания пользователь возвращается на главный экран с циферблатом. Существует два исключения:

  • Если пользователь находится в редакторе метода ввода (IME), например на экране распознавания рукописного ввода, нажатие кнопки закрывает IME и возвращает пользователя в приложение.
  • Если пользователь находится на циферблате, нажатие аппаратной кнопки открывает панель запуска приложений.

Примечание. При нажатии кнопки питания метод isFinishing() класса Activity не возвращает значение true, и вы не можете перехватить событие нажатия клавиши.

Подробнее о навигации…