Ce document explique comment suivre le style Glass et appliquer les bonnes pratiques courantes concernant l'interface utilisateur lors de l'utilisation de GDK.
Thème Glass
Glass applique un thème standard à votre Glassware de sorte qu'il reste cohérent avec le reste de l'interface utilisateur. Le thème présente les caractéristiques suivantes:
- Utilise la police Roboto
- Affiche les activités en plein écran sans barre d'état ni barre d'action.
- Arrière-plan uni noir
Pour appliquer le thème Glass, ne déclarez pas de thème dans votre fichier manifeste Android.
Si vous avez un style personnalisé pour certaines parties de Glassware et que vous souhaitez utiliser le thème Glass par défaut pour tout le reste, héritez de Theme.DeviceDefault
avec l'attribut parent
:
<resources>
<style name="CustomTheme" parent="@android:style/Theme.DeviceDefault">
<!-- Theme customization goes here. -->
</style>
</resources>
Pour en savoir plus sur la création de thèmes, consultez le guide du développeur Android sur Styles et thèmes.
Cartes stylisées
La classe CardBuilder
crée des fiches correctement formées à partir d'un ensemble de propriétés. Dans la mesure du possible, utilisez les mises en page fournies par CardBuilder.Layout
afin que votre contenu ressemble à d'autres contenus sur Glass.
Pour utiliser CardBuilder
:
- Créez une instance de
CardBuilder
en lui attribuant la mise en page souhaitée à partir deCardBuilder.Layout
. - Définissez les propriétés de la fiche, telles que le texte, la note de bas de page et l'horodatage.
- Appelez
CardBuilder.getView()
pour convertir la carte en objet AndroidView
ouCardBuilder.getRemoteViews()
pour la convertir en objetRemoteViews
. - Utilisez
View
dans vos activités, mises en page ouCardScrollView
, ouRemoteViews
dans unLiveCard
.
Fonctionnalités courantes de l'interface utilisateur
De nombreuses mises en page fournies par CardBuilder
sont compatibles avec les fonctionnalités d'interface utilisateur courantes décrites ci-dessous. Consultez la documentation de chaque mise en page dans CardBuilder.Layout
pour obtenir la liste des fonctionnalités compatibles avec chaque type de fiche.
Icône d'attribution
L'icône d'attribution est une icône facultative de 36 x 36 pixels qui apparaît dans l'angle inférieur droit d'une fiche et à droite de l'horodatage. Définissez cette icône en appelant CardBuilder.setAttributionIcon()
pour identifier votre application, en particulier sur les cartes en direct, afin qu'un utilisateur puisse rapidement voir la source des informations sur cette carte.
Indicateur de pile
L'indicateur de la pile, contrôlé par CardBuilder.showStackIndicator()
, est un pli d'angle qui apparaît dans l'angle supérieur droit d'une fiche. Utilisez-le comme indicateur visuel du fait que votre carte représente un lot de fiches sur lesquelles l'utilisateur peut appuyer directement.
View view = new CardBuilder(context, CardBuilder.Layout.TEXT)
.setText("A stack indicator can be added to the corner of a card...")
.setAttributionIcon(R.drawable.ic_smile)
.showStackIndicator(true)
.getView();
Mises en page
Les exemples suivants montrent les mises en page disponibles à l'aide de CardBuilder
.
TEXT
et TEXT_FIXED
La mise en page CardBuilder.Layout.TEXT
affiche du texte à fond perdu avec une mosaïque d'images en arrière-plan facultative. Le texte est automatiquement redimensionné pour s'adapter au mieux à l'espace disponible.
CardBuilder.Layout.TEXT_FIXED
est semblable, mais son texte est réduit.
View view1 = new CardBuilder(context, CardBuilder.Layout.TEXT)
.setText("This is the TEXT layout. The text size will adjust dynamically.")
.setFootnote("This is the footnote")
.setTimestamp("just now")
.getView();
View view2 = new CardBuilder(context, CardBuilder.Layout.TEXT)
.setText("You can also add images to the background of a TEXT card.")
.setFootnote("This is the footnote")
.setTimestamp("just now")
.addImage(R.drawable.image1)
.addImage(R.drawable.image2)
.addImage(R.drawable.image3)
.addImage(R.drawable.image4)
.addImage(R.drawable.image5)
.getView();
View view3 = new CardBuilder(context, CardBuilder.Layout.TEXT_FIXED)
.setText("This is the TEXT_FIXED layout. The text size is always the same.")
.setFootnote("This is the footnote")
.setTimestamp("just now")
.getView();
COLUMNS
et COLUMNS_FIXED
La mise en page CardBuilder.Layout.COLUMNS
affiche une mosaïque d'images ou une icône à gauche de la fiche, et du texte à droite. La taille du texte est adaptée de manière dynamique à l'espace disponible. Pour que la taille du texte reste fixe, utilisez CardBuilder.Layout.COLUMNS_FIXED
.
View view1 = new CardBuilder(context, CardBuilder.Layout.COLUMNS)
.setText("This is the COLUMNS layout with dynamic text.")
.setFootnote("This is the footnote")
.setTimestamp("just now")
.addImage(R.drawable.image1)
.addImage(R.drawable.image2)
.addImage(R.drawable.image3)
.addImage(R.drawable.image4)
.addImage(R.drawable.image5)
.getView();
View view2 = new CardBuilder(context, CardBuilder.Layout.COLUMNS)
.setText("You can even put a centered icon on a COLUMNS card instead of a mosaic.")
.setFootnote("This is the footnote")
.setTimestamp("just now")
.setIcon(R.drawable.ic_wifi)
.getView();
View view3 = new CardBuilder(context, CardBuilder.Layout.COLUMNS_FIXED)
.setText("This is the COLUMNS_FIXED layout. The text size is always the same.")
.setFootnote("This is the footnote")
.setTimestamp("just now")
.addImage(R.drawable.image1)
.addImage(R.drawable.image2)
.addImage(R.drawable.image3)
.addImage(R.drawable.image4)
.addImage(R.drawable.image5)
.getView();
CAPTION
La mise en page CardBuilder.Layout.CAPTION
comporte une mosaïque d'images en arrière-plan et un bref texte de sous-titres aligné au bas de la fiche. Une icône peut également être placée à côté de la légende pour représenter, par exemple, l'identité d'une personne associée au contenu de la fiche.
View view1 = new CardBuilder(context, CardBuilder.Layout.CAPTION)
.setText("The caption layout.")
.setFootnote("This is the footnote")
.setTimestamp("just now")
.addImage(R.drawable.beach)
.setAttributionIcon(R.drawable.ic_smile)
.getView();
View view2 = new CardBuilder(context, CardBuilder.Layout.CAPTION)
.setText("The caption layout with an icon.")
.setFootnote("This is the footnote")
.setTimestamp("just now")
.addImage(R.drawable.beach)
.setIcon(R.drawable.ic_avatar)
.setAttributionIcon(R.drawable.ic_smile)
.getView();
TITLE
La mise en page CardBuilder.Layout.TITLE
présente une mosaïque d'images en arrière-plan avec un titre centré et une icône facultative au bas de la fiche. Cette mise en page est souvent utilisée pour représenter des contacts ou des cibles de partage. Les notes de bas de page et l'horodatage ne sont pas compatibles avec cette mise en page.
View view = new CardBuilder(context, CardBuilder.Layout.TITLE)
.setText("TITLE Card")
.setIcon(R.drawable.ic_phone)
.addImage(R.drawable.beach)
.getView();
AUTHOR
Utilisez la mise en page CardBuilder.Layout.AUTHOR
pour afficher un message ou une conversation dont l'auteur est l'auteur. Il accepte une mosaïque d'images en arrière-plan, une icône utilisée comme avatar de l'auteur, ainsi qu'un titre et un sous-titre où vous pouvez lister les informations d'identification.
View view = new CardBuilder(context, CardBuilder.Layout.AUTHOR)
.setText("The AUTHOR layout lets you display a message or conversation "
+ " with a focus on the author.")
.setIcon(R.drawable.ic_avatar)
.setHeading("Joe Lastname")
.setSubheading("Mountain View, California")
.setFootnote("This is the footnote")
.setTimestamp("just now")
.getView();
MENU
La mise en page CardBuilder.Layout.MENU
ressemble à un menu Glass standard. Elle comporte une icône et un titre centrés, ainsi qu'une note de bas de page facultative. Utilisez cette mise en page pour les écrans de confirmation (passage de "Suppression" à "Supprimé" après que l'utilisateur a sélectionné un élément de menu, par exemple). Si vous avez besoin d'un vrai menu, utilisez plutôt un menu d'options standard.
View view = new CardBuilder(context, CardBuilder.Layout.MENU)
.setText("MENU layout")
.setIcon(R.drawable.ic_phone)
.setFootnote("Optional menu description")
.getView();
EMBED_INSIDE
La mise en page CardBuilder.Layout.EMBED_INSIDE
intègre un XML de mise en page personnalisé de votre propre conception dans le modèle standard de la fiche Glass. Cela vous permet de concevoir une interface utilisateur personnalisée pour votre application tout en conservant un emplacement correct de la note de bas de page, de l'horodatage, de l'icône d'attribution et de l'indicateur de pile d'une carte, si nécessaire.
Après avoir appelé CardBuilder.getView()
, utilisez findViewById()
sur le résultat pour accéder aux vues dans votre mise en page intégrée. De même, si vous appelez CardBuilder.getRemoteViews()
, vous pouvez manipuler les vues de la mise en page intégrée en transmettant leurs ID directement dans les méthodes "set" de la méthode RemoteViews
.
View view = new CardBuilder(context, CardBuilder.Layout.EMBED_INSIDE)
.setEmbeddedLayout(R.layout.food_table)
.setFootnote("Foods you tracked")
.setTimestamp("today")
.getView();
TextView textView1 = (TextView) view.findViewById(R.id.text_view_1);
textView1.setText("Water");
// ...and so on
Pour obtenir un exemple plus détaillé, consultez le projet ApiDemo sur GitHub.
ALERT
La mise en page CardBuilder.Layout.ALERT
contient une grande icône centrée avec un message principal et une note de bas de page. Utilisez cette mise en page dans un Dialog
pour afficher un message d'information important, un avertissement ou une erreur dans votre Glassware.
L'exemple suivant montre une implémentation de AlertDialog
, qui ferme la carte et ouvre les paramètres Wi-Fi lorsque l'utilisateur appuie dessus:
- Créez une classe qui étend
Dialog
. - Créez la fiche à l'aide de
CardBuilder
avec la mise en pageCardBuilder.Layout.ALERT
, puis définissez la vue du contenu avec cette fiche. (Facultatif) Créez un
{15/)GestureDetector
pour gérer les gestes de l'utilisateur sur cette fiche.(Facultatif) Dans votre activité, implémentez un
OnClickListener
pour gérer les flux supplémentaires lorsque l'utilisateur appuie. Pour en savoir plus sur le démarrage d'activités liées aux paramètres, tels que le Wi-Fi, consultez la section Paramètres de démarrage.Appelez le constructeur
AlertDialog
pour afficher la fiche d'alerte.public class MyActivity extends Activity { ... private final DialogInterface.OnClickListener mOnClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int button) { // Open WiFi Settings startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); } }; @Override protected void onCreate(Bundle bundle) { ... new AlertDialog(context, R.drawable.ic_cloud_sad_150, R.string.alert_text, R.string.alert_footnote_text, mOnClickListener).show(); ... } }
Mises en page XML
Voici deux mises en page de fiches de base que vous pouvez utiliser si la classe CardBuilder ne répond pas à vos besoins.
Mise en page principale
Cette mise en page définit la marge intérieure et le pied de page standards d'une fiche. Placez vos propres vues dans le RelativeLayout
vide.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:id="@+id/body_layout"
android:layout_width="match_parent"
android:layout_height="@dimen/glass_card_body_height"
android:layout_marginLeft="@dimen/glass_card_margin"
android:layout_marginTop="@dimen/glass_card_margin"
android:layout_marginRight="@dimen/glass_card_margin"
tools:ignore="UselessLeaf"
>
<!-- Put your widgets inside this RelativeLayout. -->
</RelativeLayout>
<LinearLayout
android:id="@+id/footer_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|left"
android:layout_marginLeft="@dimen/glass_card_margin"
android:layout_marginBottom="@dimen/glass_card_footer_margin"
android:layout_marginRight="@dimen/glass_card_margin"
android:orientation="horizontal"
>
<!-- The footer view will grow to fit as much content as possible while the
timestamp view keeps a fixed width. If the footer text is too long, it
will be ellipsized with a 40px margin between it and the timestamp. -->
<TextView
android:id="@+id/footer"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/glass_card_margin"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
</LinearLayout>
</FrameLayout>
Disposition à gauche
Elle définit une colonne de gauche de 240 pixels et une colonne de droite de 400 pixels sous forme de deux éléments RelativeLayout
dans lesquels vous pouvez placer vos vues.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
>
<RelativeLayout
android:id="@+id/left_column"
android:layout_width="@dimen/glass_card_left_column_width"
android:layout_height="match_parent"
>
<!-- Put widgets for the left column inside this RelativeLayout. -->
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="@dimen/glass_card_body_height"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="@dimen/glass_card_two_column_margin"
android:layout_marginRight="@dimen/glass_card_margin"
android:layout_marginTop="@dimen/glass_card_margin"
android:layout_toRightOf="@+id/left_column"
tools:ignore="UselessLeaf"
>
<!-- Put widgets for the right column inside this RelativeLayout. -->
</RelativeLayout>
<LinearLayout
android:id="@+id/footer_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_gravity="bottom|left"
android:layout_marginBottom="@dimen/glass_card_footer_margin"
android:layout_marginLeft="@dimen/glass_card_two_column_margin"
android:layout_marginRight="@dimen/glass_card_margin"
android:layout_toRightOf="@+id/left_column"
android:orientation="horizontal"
>
<!--
The footer view will grow to fit as much content as possible while the
timestamp view keeps a fixed width. If the footer text is too long, it
will be ellipsized with a 40px margin between it and the timestamp.
-->
<TextView
android:id="@+id/footer"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/glass_card_margin"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
</LinearLayout>
</RelativeLayout>
Dimensions standards
Utilisez ce fichier avec les mises en page précédentes ou avec vos propres mises en page pour respecter le style Glass standard. Créez ce fichier en tant que res/values/dimens.xml
dans votre projet 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">40px</dimen>
<!-- The recommended margin between the bottom of the card and the footer. This is
an adjusted value so that the baseline of the text in the footer sits 40px
from the bottom of the card, matching the other margins. -->
<dimen name="glass_card_footer_margin">33px</dimen>
<!-- The recommended margin for the left column of the two-column card. -->
<dimen name="glass_card_two_column_margin">30px</dimen>
<!-- The maximum height of the body content inside a card. -->
<dimen name="glass_card_body_height">240px</dimen>
<!-- The width of the left column in the two-column layout. -->
<dimen name="glass_card_left_column_width">240px</dimen>
</resources>