Z tego dokumentu dowiesz się, jak zachować zgodność ze stylem Glass i wdrażać typowe sprawdzone metody dotyczące interfejsu podczas korzystania z GDK.
Motyw szklany
Google Glass stosuje standardowy motyw, dzięki czemu zachowuje spójność z pozostałymi elementami interfejsu. motyw ma te cechy:
- Używa kroju Roboto.
- Wyświetla aktywności na pełnym ekranie bez paska stanu ani paska działań
- Zastosuj jednolite, czarne tło
Aby zastosować motyw Glass, nie deklaruj motywu w pliku manifestu Androida.
Jeśli masz niestandardowy styl dla części oprogramowania Glassware
i chcą ustawić domyślny motyw Glass dla całej reszty,
odziedzicz po Theme.DeviceDefault
za pomocą atrybutu parent
:
<resources>
<style name="CustomTheme" parent="@android:style/Theme.DeviceDefault">
<!-- Theme customization goes here. -->
</style>
</resources>
Zobacz przewodnik dla programistów aplikacji na Androida na stronie Style i motywy .
Karty ze szkła
CardBuilder
tworzy prawidłowo sformatowane karty z danym zestawem właściwości. Korzystanie z układów
źródło: CardBuilder.Layout
aby Twoje materiały wyglądały i wyglądały jak inne
Szkło.
Aby użyć aplikacji CardBuilder
:
- Utwórz instancję
CardBuilder
, zapewniając jej odpowiedni układ z:CardBuilder.Layout
- Ustaw właściwości karty, takie jak tekst, przypis i sygnatura czasowa.
- Zadzwoń pod numer
CardBuilder.getView()
aby przekonwertować kartę na AndroidaView
lubCardBuilder.getRemoteViews()
aby przekonwertować go naRemoteViews
obiektu. - Korzystaj z
View
w aktywnościach, układach i naCardScrollView
lub skorzystaj zRemoteViews
wLiveCard
.
Wspólne funkcje interfejsu
Wiele układów oferowanych przez CardBuilder
obsługuje wspólny interfejs
funkcji opisanych poniżej. Dokumentację poszczególnych układów znajdziesz w
CardBuilder.Layout
, gdzie znajdziesz listę funkcji obsługiwanych przez poszczególne typy kart.
Ikona informacji
Ikona informacji to opcjonalna ikona o wymiarach 36 × 36 pikseli, widoczna na
w prawym dolnym rogu karty i po prawej stronie sygnatury czasowej. Ustaw
, dzwoniąc
CardBuilder.setAttributionIcon()
do identyfikacji aplikacji, szczególnie na aktywnych kartach,
i sprawdzić źródło informacji na danej karcie.
Wskaźnik stosu
Wskaźnik stosu, kontrolowany przez
CardBuilder.showStackIndicator()
to zagięcie narożnika widoczne w prawym górnym rogu karty. Użyj tego jako:
aby wskazać, że karta reprezentuje inne karty, których
użytkownik może kliknąć reklamę.
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();
Układy
W przykładach poniżej pokazujemy układy, które są dostępne przy użyciu
CardBuilder
TEXT
i TEXT_FIXED
CardBuilder.Layout.TEXT
Układ strony zawiera tekst na całym ekranie z opcjonalnym elementem
mozaika obrazów w tle. Rozmiar tekstu dynamicznie się zmienia, by jak najlepiej go dopasować
dostępnego miejsca.
CardBuilder.Layout.TEXT_FIXED
jest podobny, ale zmniejsza rozmiar tekstu.
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
i COLUMNS_FIXED
CardBuilder.Layout.COLUMNS
na zdjęciu może mieć mozaikę lub ikonę.
po lewej stronie karty i tekstu po prawej. Rozmiar tekstu jest dynamicznie dostosowywany
aby jak najlepiej pasowały do dostępnej przestrzeni. Aby utrzymać stały rozmiar tekstu, użyj
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
CardBuilder.Layout.CAPTION
układ zawiera mozaikę w tle
i krótki tekst napisów wyrównany u dołu karty. Można też użyć ikony
umieszczone obok podpisu, aby reprezentować np. tożsamość osoby
powiązane z treścią karty.
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
CardBuilder.Layout.TITLE
układ zawiera mozaikę w tle
z wyśrodkowanym tytułem i opcjonalną ikoną u dołu karty. Ten układ
jest często używany do reprezentowania kontaktów lub udostępniania celów. Przypis i sygnatura czasowa są
nie jest obsługiwane w tym układzie.
View view = new CardBuilder(context, CardBuilder.Layout.TITLE)
.setText("TITLE Card")
.setIcon(R.drawable.ic_phone)
.addImage(R.drawable.beach)
.getView();
AUTHOR
Użyj
CardBuilder.Layout.AUTHOR
układ do wyświetlania wiadomości lub wątku
w których kładzie się nacisk na autora. obsługuje mozaikę obrazów w tle,
ikonę, która służy jako awatar autora, oraz nagłówek i podtytuł,
listę danych identyfikacyjnych.
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
CardBuilder.Layout.MENU
układ wygląda jak standardowe menu Google Glass. Zawiera
wyśrodkowaną ikonę, tytuł i opcjonalny przypis. Użyj tego układu do:
ekranów potwierdzenia (przejście z „Deletion” (usuwanie) na „Remove” (usunięcie) po
(np. wybierz pozycję menu). Jeśli potrzebujesz prawdziwego menu, skorzystaj z
standardowego menu opcji.
View view = new CardBuilder(context, CardBuilder.Layout.MENU)
.setText("MENU layout")
.setIcon(R.drawable.ic_phone)
.setFootnote("Optional menu description")
.getView();
EMBED_INSIDE
CardBuilder.Layout.EMBED_INSIDE
układ zawiera kod XML własnego układu w standardowym Google Glass
szablon karty. Pozwala to zaprojektować niestandardowy interfejs aplikacji,
ma prawidłowe umieszczenie przypisu, sygnatury czasowej, ikony atrybucji i prawidłowego umieszczenia przypisu do karty;
stosu wywołań w razie potrzeby.
Po nawiązaniu połączenia
CardBuilder.getView()
należy użyć funkcji
findViewById()
i uzyskać dostęp do widoków w umieszczonym układzie. Podobnie, jeśli
zadzwoń
CardBuilder.getRemoteViews()
możesz manipulować widokami układu umieszczonego, przekazując ich identyfikatory bezpośrednio
w sekcji
RemoteViews
metody ustawiania.
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
Bardziej szczegółowy przykład znajdziesz w GitHubie Projekt Apigee.
ALERT
CardBuilder.Layout.ALERT
układ zawiera dużą wyśrodkowaną ikonę z
wiadomości głównej i przypisu. Użyj tego układu w
Dialog
do
w Google Glassware pojawi się ważny komunikat informacyjny, ostrzeżenie lub błąd.
Poniższy przykład pokazuje implementację interfejsu AlertDialog
i zamieszcza
i otwiera ustawienia Wi-Fi, gdy użytkownik kliknie kartę:
- Utwórz zajęcia z rozszerzeniem
Dialog
. - Utwórz kartę za pomocą elementu
CardBuilder
z układemCardBuilder.Layout.ALERT
, a następnie ustaw widok treści za pomocą tej karty. (Opcjonalnie) Utwórz
GestureDetector
do obsługi gestów użytkownika na tej karcie.public class AlertDialog extends Dialog { private final DialogInterface.OnClickListener mOnClickListener; private final AudioManager mAudioManager; private final GestureDetector mGestureDetector; /** * Handles the tap gesture to call the dialog's * onClickListener if one is provided. */ private final GestureDetector.BaseListener mBaseListener = new GestureDetector.BaseListener() { @Override public boolean onGesture(Gesture gesture) { if (gesture == Gesture.TAP) { mAudioManager.playSoundEffect(Sounds.TAP); if (mOnClickListener != null) { // Since Glass dialogs do not have buttons, // the index passed to onClick is always 0. mOnClickListener.onClick(AlertDialog.this, 0); } return true; } return false; } }; public AlertDialog(Context context, int iconResId, int textResId, int footnoteResId, DialogInterface.OnClickListener onClickListener) { super(context); mOnClickListener = onClickListener; mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mGestureDetector = new GestureDetector(context).setBaseListener(mBaseListener); setContentView(new CardBuilder(context, CardBuilder.Layout.ALERT) .setIcon(iconResId) .setText(textResId) .setFootnote(footnoteResId) .getView()); } /** Overridden to let the gesture detector handle a possible tap event. */ @Override public boolean onGenericMotionEvent(MotionEvent event) { return mGestureDetector.onMotionEvent(event) || super.onGenericMotionEvent(event); } }
(Opcjonalnie) W aktywności zaimplementuj
OnClickListener
obsługi dodatkowych procesów, gdy użytkownik kliknie reklamę. Więcej informacji na temat: uruchamianie ustawień takich jak Wi-Fi, zobacz Ustawienia początkowe.Aby wyświetlić kartę alertu, wywołaj konstruktor
AlertDialog
.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(); ... } }
Układy XML
Oto 2 podstawowe układy kart, których możesz użyć, jeśli klasa CardBuilder który nie odpowiada Twoim potrzebom.
Układ główny
Ten układ definiuje standardowe dopełnienie i stopkę karty. Dodaj własne
widoków w pustym RelativeLayout
.
<?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>
Układ lewej kolumny
Definiuje lewą kolumnę o długości 240 pikseli i prawą o 400 pikseli. Mają postać dwóch kolumn RelativeLayout
.
który możesz wykorzystać.
<?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>
Wymiary standardowe
Użyj tego pliku w połączeniu z poprzednimi lub własnymi układami, aby
są zgodne ze standardowym stylem Glass. Utwórz ten plik jako
res/values/dimens.xml
w projekcie na Androida.
<?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>