Пользовательский интерфейс

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

Тема

Тема Glass, которую мы предлагаем вам использовать, имеет следующие характеристики:

  • Отображает действия в полноэкранном режиме без панели действий.
  • Применяет сплошной черный фон.
  • Устанавливает более светлый цвет для эффекта цветового края.
  • Применяет белый цвет текста.

Ниже приведены рекомендуемые настройки темы для Glass:

 <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
   <item name="android:windowBackground">@android:color/black</item>
   <item name="android:colorEdgeEffect">@android:color/white</item>
   <item name="android:textColor">@android:color/white</item>
 </style>

XML-макеты

Вот два основных расклада карт, которые могут раздувать ваши фрагменты:

Основной макет

Этот макет определяет предлагаемые стандартные отступы и нижний колонтитул для карточки. Поместите свои представления в пустой FrameLayout .

Центральное поле занимает большую часть внутренней части экрана с разрешением 560 на 240 пикселей, а небольшая полоса внизу имеет разрешение 560 на 40 пикселей. Также есть четыре небольших блока 40 на 40 пикселей, по одному в каждом углу.

Вот пример макета XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <FrameLayout
      android:id="@+id/body_layout"
      android:layout_width="0dp"
      android:layout_height="0dp"
      android:layout_margin="@dimen/glass_card_margin"
      app:layout_constraintBottom_toTopOf="@id/footer"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent">

    <!-- Put your widgets inside this FrameLayout. -->

  </FrameLayout>

  <!-- The footer view will grow to fit as much content as possible while the
         timestamp view keeps its width. If the footer text is too long, it
         will be ellipsized with a 40dp margin between it and the timestamp. -->

  <TextView
      android:id="@+id/footer"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginStart="@dimen/glass_card_margin"
      android:layout_marginEnd="@dimen/glass_card_margin"
      android:layout_marginBottom="@dimen/glass_card_margin"
      android:ellipsize="end"
      android:singleLine="true"
      android:textAppearance="?android:attr/textAppearanceSmall"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toStartOf="@id/timestamp"
      app:layout_constraintStart_toStartOf="parent" />

  <TextView
      android:id="@+id/timestamp"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginEnd="@dimen/glass_card_margin"
      android:layout_marginBottom="@dimen/glass_card_margin"
      android:ellipsize="end"
      android:singleLine="true"
      android:textAlignment="viewEnd"
      android:textAppearance="?android:attr/textAppearanceSmall"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Макет левой колонки

Этот макет определяет левый столбец шириной в одну треть и правый столбец шириной в две трети в виде двух классов FrameLayout , в которые вы можете поместить свои представления. Обратитесь к следующему рисунку, чтобы увидеть пример.

Отображает левый столбец размером 240 на 360 пикселей, который выдвигает основной макет. Его размер умещается, основная область 330 на 240 пикселей, с небольшой нижней полосой 330 на 40 пикселей. В двух правых углах есть два небольших блока размером 40 на 40 пикселей, а также четыре других блока размером 30 на 40 пикселей, два в нижних углах левого столбца и два в левой части основного макета, один сверху и один снизу. нижний.

Вот пример макета XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <FrameLayout
      android:id="@+id/left_column"
      android:layout_width="0dp"
      android:layout_height="match_parent"
      android:background="#303030"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintWidth_percent=".333">

    <!-- Put widgets for the left column inside this FrameLayout. -->

  </FrameLayout>

  <FrameLayout
      android:id="@+id/right_column"
      android:layout_width="0dp"
      android:layout_height="0dp"
      android:layout_marginTop="@dimen/glass_card_two_column_margin"
      android:layout_marginStart="@dimen/glass_card_two_column_margin"
      android:layout_marginBottom="@dimen/glass_card_two_column_margin"
      android:layout_marginEnd="@dimen/glass_card_margin"
      app:layout_constraintBottom_toTopOf="@id/footer"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toEndOf="@id/left_column"
      app:layout_constraintTop_toTopOf="parent">

    <!-- Put widgets for the right column inside this FrameLayout. -->

  </FrameLayout>

  <!-- The footer view will grow to fit as much content as possible while the
         timestamp view keeps its width. If the footer text is too long, it
         will be ellipsized with a 40dp margin between it and the timestamp. -->

  <TextView
      android:id="@+id/footer"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginStart="@dimen/glass_card_margin"
      android:layout_marginEnd="@dimen/glass_card_margin"
      android:layout_marginBottom="@dimen/glass_card_margin"
      android:ellipsize="end"
      android:singleLine="true"
      android:textAppearance="?android:attr/textAppearanceSmall"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toStartOf="@id/timestamp"
      app:layout_constraintStart_toEndOf="@id/left_column" />

  <TextView
      android:id="@+id/timestamp"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      android:layout_marginEnd="@dimen/glass_card_margin"
      android:layout_marginBottom="@dimen/glass_card_margin"
      android:ellipsize="end"
      android:singleLine="true"
      android:textAlignment="viewEnd"
      android:textAppearance="?android:attr/textAppearanceSmall"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Стандартные размеры

Используйте следующее в сочетании с предыдущими макетами или вашими собственными макетами, чтобы создать файл, соответствующий стандартному стилю Glass. Создайте этот файл как res/values/dimens.xml в своем проекте Android.

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <!-- The recommended margin for the top, left, and right edges of a card. -->
  <dimen name="glass_card_margin">40dp</dimen>

  <!-- The recommended margin between the bottom of the card and the footer. -->
  <dimen name="glass_card_footer_margin">50dp</dimen>

  <!-- The recommended margin for the left column of the two-column card. -->
  <dimen name="glass_card_two_column_margin">30dp</dimen>

</resources>

Мы предлагаем вам использовать RecyclerView для создания меню. Они должны быть основаны на стандартном файле меню Android из ресурсов проекта Android Studio. Android позволяет переопределить стандартное создание меню и заменить его своей реализацией. Для этого выполните следующие действия:

  1. Создайте макет с помощью RecyclerView и установите его в качестве представления для своей Activity .
  2. Настройте RecyclerView и его адаптер на использование только что созданной коллекции элементов меню.
  3. Переопределите метод onCreateOptionsMenu .
    1. Раздуйте свое меню и добавьте новый элемент в коллекцию для каждого пункта меню.
    2. Вызовите метод notifyDataSetChanged на адаптере.

    Котлин

        override fun onCreateOptionsMenu(menu: Menu): Boolean {
            val menuResource = intent
                .getIntExtra(EXTRA_MENU_KEY, EXTRA_MENU_ITEM_DEFAULT_VALUE)
            if (menuResource != EXTRA_MENU_ITEM_DEFAULT_VALUE) {
                menuInflater.inflate(menuResource, menu)
                for (i in 0 until menu.size()) {
                    val menuItem = menu.getItem(i)
                    menuItems.add(
                        GlassMenuItem(
                            menuItem.itemId, menuItem.icon,
                            menuItem.title.toString()
                        )
                    )
                    adapter.notifyDataSetChanged()
                }
            }
            return super.onCreateOptionsMenu(menu)
        }
        

    Ява

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
          final int menuResource = getIntent()
              .getIntExtra(EXTRA_MENU_KEY, EXTRA_MENU_ITEM_DEFAULT_VALUE);
          if (menuResource != EXTRA_MENU_ITEM_DEFAULT_VALUE) {
            final MenuInflater inflater = getMenuInflater();
            inflater.inflate(menuResource, menu);
    
            for (int i = 0; i < menu.size(); i++) {
              final MenuItem menuItem = menu.getItem(i);
              menuItems.add(
                  new GlassMenuItem(menuItem.getItemId(), menuItem.getIcon(),
                      menuItem.getTitle().toString()));
              adapter.notifyDataSetChanged();
            }
          }
          return super.onCreateOptionsMenu(menu);
        }
        
  4. Используйте OnScrollListener вместе с LayoutManager и SnapHelper , чтобы определить, какой вариант был выбран.
  5. Прослушайте жест TAP , чтобы обработать событие выбора пункта меню.
  6. Создайте Intent с информацией о выбранном пункте меню.
  7. Установите результат для этого действия и завершите его.
  8. Вызовите startActivityForResult из фрагмента или действия, где вы хотите иметь меню. Для этого используйте жест TAP .
  9. Переопределите onActivityResult в вызывающем фрагменте или действии для обработки выбранного пункта меню.

Методические рекомендации

Ниже приведен список рекомендаций по настройке макета меню:

На следующем изображении показан пример пользовательского макета меню:

На этом простом изображении показан черный фон со словами «Раскладка МЕНЮ» по центру экрана и символом телефона рядом.

Ознакомьтесь с образцом приложения Card, чтобы узнать подробности реализации.

Перелистываемые страницы

Стеклянный дисплей и сенсорная панель работают вместе, чтобы удобно отображать карты, которые можно смахивать. Вы можете создавать перелистываемые страницы в своей деятельности с помощью стандартного Android ViewPager API.

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