En este documento, se explica cómo seguir el estilo de Glass y cómo implementar prácticas recomendadas comunes de la IU que pueden optimizar la experiencia del usuario. Abarca los siguientes elementos de la IU:
Tema
El tema de Glass que sugerimos que utilices tiene las siguientes características:
- Muestra las actividades en pantalla completa sin barra de acciones.
- Aplica un fondo negro liso.
- Establece el color más claro para el efecto de borde de color.
- Aplica un color de texto blanco.
Las siguientes son las opciones de configuración de temas recomendadas 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 de tarjeta básicos que pueden ampliar tus fragmentos:
Diseño principal
Este diseño define el padding estándar y el pie de página sugeridos para una tarjeta. Coloca tus propias vistas en el FrameLayout
vacío.

Este es un ejemplo de diseño 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 la columna izquierda
Este diseño define una columna de ancho izquierdo de un tercio y una columna de ancho de dos tercios derecha en forma de dos clases FrameLayout
en las que puedes colocar tus vistas. Consulta la siguiente imagen para ver un ejemplo.

Este es un ejemplo de diseño 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 con 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>
Menús
Te sugerimos que uses RecyclerView
para compilar menús. Se deben basar en el archivo de menú estándar de Android de los recursos del proyecto de Android Studio. Android te permite anular la creación del menú estándar y reemplazarla con tu implementación. Para ello, haz lo siguiente:
- Crea el diseño con
RecyclerView
y establécelo como la vista de tuActivity
. - Configura
RecyclerView
y su adaptador para usar la colección recién creada de elementos del menú. - Anula el método
onCreateOptionsMenu
.- Aumenta tu menú y agrega el nuevo elemento a la colección para cada elemento del menú.
- 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); }
- Usa
OnScrollListener
junto conLayoutManager
ySnapHelper
para determinar qué opción se seleccionó. - Escucha un gesto de
TAP
para controlar el evento de selección del elemento de menú. - Crea un
Intent
con información sobre el elemento de menú seleccionado. - Establece un resultado para esta actividad y complétalo.
- Llama a
startActivityForResult
desde el fragmento o la actividad en los que quieras tener un menú. Para ello, usa un gesto deTAP
. - Anula
onActivityResult
en la actividad o el fragmento que realiza la llamada para controlar el elemento de menú seleccionado.
Lineamientos
La siguiente es una lista de sugerencias sobre cómo configurar el diseño del menú:
- Tamaño del texto:
64sp
- Color de fondo:
#96000000
- Usa íconos de material con un tamaño de
64dpx64dp
- Establece la marca de tema
windowIsTranslucent
entrue
La siguiente imagen es un ejemplo de un diseño de menú personalizado:

Revisa la app de muestra de tarjeta para ver los detalles de la implementación.
Páginas deslizables
La pantalla y el panel táctil de Glass funcionan en conjunto para mostrar tarjetas deslizables de una manera conveniente. Puedes crear páginas deslizables en tu actividad con la API estándar de ViewPager
de Android.
Consulta la documentación de capacitación sobre la Diapositiva de pantalla para obtener más información sobre cómo usar Android ViewPager
a fin de desplazarte por las tarjetas o las pantallas.