Interfaz de usuario

En este documento, se explica cómo seguir el estilo de Glass y aplicar las prácticas recomendadas comunes de la IU que pueden optimizar la experiencia del usuario. Abarca los siguientes elementos de la IU:

Tema

El tema Glass que te sugerimos usar tiene las siguientes características:

  • Muestra las actividades en pantalla completa sin barra de acción.
  • Aplica un fondo negro sólido.
  • Establece el color más claro para el efecto de borde de color.
  • Aplica un color de texto blanco.

A continuación, se indican los parámetros de configuración del tema recomendados para 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>

Diseños XML

Estos son los dos diseños básicos de tarjetas que pueden inflar tus fragmentos:

Diseño principal

Este diseño define el padding y el pie de página estándar sugeridos para una tarjeta. Coloca tus propias vistas en el FrameLayout vacío.

El cuadro central ocupa la mayor parte del interior de la pantalla con 560 por 240 píxeles, con una pequeña barra en la parte inferior de 560 por 40 píxeles.
          También hay cuatro pequeños bloques de 40 x 40 píxeles, uno en cada esquina.

A continuación, se muestra un ejemplo de diseño en 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>

Diseño de columna izquierda

Este diseño define una columna izquierda de un tercio de ancho y una columna derecha de dos tercios de ancho en forma de dos clases FrameLayout en las que puedes colocar tus vistas. Consulta la siguiente imagen para ver un ejemplo.

Muestra una columna izquierda de 240 x 360 píxeles, lo que desplaza el diseño principal.
          Su tamaño se ajusta para adaptarse, el área principal es de 330 por 240 píxeles, con una pequeña barra inferior de 330 por 40 píxeles. Las dos esquinas derechas tienen dos pequeños cuadros de 40 x 40 píxeles, y hay otros cuatro cuadros de 30 x 40 píxeles, dos en las esquinas inferiores de la columna izquierda y dos en el lado izquierdo del diseño principal, uno en la parte superior y otro en la inferior.

A continuación, se muestra un ejemplo de diseño en 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>

Dimensiones estándar

Usa lo siguiente junto con los diseños anteriores o tus propios diseños para crear un archivo que cumpla con el estilo estándar de Glass. Crea este archivo como res/values/dimens.xml en tu proyecto de 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>

Te sugerimos que uses RecyclerView para crear menús. Deben basarse en el archivo de menú estándar de Android de los recursos del proyecto de Android Studio. Android te permite anular la creación estándar de menús y reemplazarla por tu propia implementación. Para hacerlo, sigue estos pasos:

  1. Crea el diseño con RecyclerView y establécelo como la vista de tu Activity.
  2. Configura RecyclerView y su adaptador para usar la colección de elementos de menú recién creada.
  3. Anula el método onCreateOptionsMenu.
    1. Infla tu menú y agrega el elemento nuevo a la colección para cada elemento del menú.
    2. Llama al método notifyDataSetChanged en el 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. Usa OnScrollListener junto con LayoutManager y SnapHelper para determinar qué opción se seleccionó.
  5. Detecta un gesto de TAP para controlar el evento de selección del elemento de menú.
  6. Crea un objeto Intent con información sobre el elemento de menú seleccionado.
  7. Establece un resultado para esta actividad y finalízala.
  8. Llama a startActivityForResult desde el fragmento o la actividad en la que quieras tener un menú. Para ello, usa un gesto de TAP.
  9. Anula onActivityResult en el fragmento o la actividad de llamada para controlar el elemento de menú seleccionado.

Lineamientos

A continuación, se incluye una lista de sugerencias para configurar el diseño del menú:

La siguiente imagen es un ejemplo de un diseño de menú personalizado:

Esta imagen simple muestra un fondo negro con las palabras &quot;Diseño de MENÚ&quot; centradas en la pantalla y un símbolo de teléfono junto a ellas.

Revisa la app de ejemplo de tarjetas para obtener detalles sobre la implementación.

Páginas deslizables

La pantalla y el panel táctil de Glass funcionan en conjunto para mostrar tarjetas que se pueden deslizar de forma conveniente. Puedes compilar páginas deslizables en tu actividad con la API estándar de Android ViewPager.

Visita la documentación de capacitación sobre Deslizamiento de pantalla para obtener más información sobre cómo usar ViewPager de Android para desplazarte por tarjetas o pantallas.