Interface do usuário

Este documento explica como seguir o estilo do Glass e implementar práticas recomendadas da IU comuns que podem otimizar a experiência do usuário. Ele abrange os seguintes elementos da IU:

Tema

Sugerimos que o tema do Glass seja baseado nas seguintes características:

  • Exibe as atividades em tela cheia, sem barra de ação.
  • Aplica um plano de fundo preto sólido.
  • Define o brilho da cor para o efeito de borda.
  • Aplica uma cor de texto branca.

Veja a seguir as configurações de tema recomendadas para o Google 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>

Layouts XML

Veja os dois layouts básicos de card que os fragmentos podem inflar:

Layout principal

Esse layout define o padding e o rodapé padrão sugeridos para um cartão. Coloque suas próprias visualizações no FrameLayout vazio.

A caixa central ocupa a maior parte do interior da tela a 560 por 240 pixels, com
          uma pequena barra na parte inferior que é de 560 por 40 pixels.
          Também há quatro blocos pequenos de 40 x 40 pixels, um em cada canto

Veja um exemplo de layout 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>

Layout da coluna à esquerda

Esse layout define uma coluna de um terço para a esquerda e dois terços de largura para a direita na forma de duas classes FrameLayout em que você pode colocar suas visualizações. Veja na imagem a seguir um exemplo.

Mostra uma coluna à esquerda com 240 por 360 pixels, que empurra o layout principal.
          O tamanho é espremido. A área principal é de 330 x 240 pixels com uma pequena barra menor que 330 x 40 pixels. Os dois cantos direito têm duas caixas pequenas de 40 x 40 pixels e
          há quatro outras caixas de 30 x 40 pixels, duas nos cantos inferiores da coluna à esquerda
          e duas no lado esquerdo do layout principal, uma na parte superior e uma na parte inferior.

Veja um exemplo de layout 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>

Dimensões padrão

Use o seguinte com os layouts anteriores ou seus próprios layouts para criar um arquivo que seja compatível com o estilo padrão do Glass&#39. Crie esse arquivo como res/values/dimens.xml no projeto do 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>

Sugerimos usar RecyclerView para criar menus. Eles precisam ser baseados no arquivo de menu padrão do Android a partir dos recursos do projeto do Android Studio. O Android permite substituir a criação de menus padrão e substituí-la pela implementação. Para isso, siga estas etapas:

  1. Crie o layout com RecyclerView e defina-o como a visualização do Activity.
  2. Defina RecyclerView e o adaptador para usar a nova coleção de itens de menu.
  3. Modifique o método onCreateOptionsMenu.
    1. Aumente o menu e adicione um elemento novo à coleção de cada item.
    2. Chame o método notifyDataSetChanged no adaptador.

    Kotlin

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

    Java

        @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. Use OnScrollListener com LayoutManager e SnapHelper para determinar qual opção foi selecionada.
  5. Escute um gesto TAP para processar o evento de seleção do item de menu.
  6. Crie uma Intent com informações sobre o item de menu selecionado.
  7. Defina um resultado para essa atividade e conclua-o.
  8. Chame startActivityForResult do fragmento ou da atividade em que você quer criar um menu. Use um gesto TAP para essa finalidade.
  9. Substitua o onActivityResult no fragmento ou na atividade de chamada para processar o item de menu selecionado.

Diretrizes

Veja uma lista de sugestões sobre como configurar o layout do menu:

A imagem a seguir é um exemplo de um layout de menu personalizado:

Esta imagem simples mostra um plano de fundo preto com as palavras &quot;#39;layout MENU&quot;#39; centralizados na
       tela e um símbolo de telefone adjacente.

Revise o app de amostra de card para ver detalhes de implementação.

Páginas deslizantes

A tela do Google Glass e o touchpad trabalham juntos para mostrar cards deslizantes de uma forma conveniente. Você pode criar páginas deslizantes na sua atividade com a API ViewPager padrão do Android.

Acesse a documentação de treinamento do Slide de tela para mais informações sobre como usar o Android ViewPager para navegar pelos cards ou telas.