Dokumen ini membahas cara mengikuti gaya Glass dan menerapkan praktik terbaik UI umum saat menggunakan GDK.
Tema kaca
Glass menerapkan tema standar ke Glassware Anda, sehingga tetap konsisten dengan seluruh antarmuka pengguna. Tujuan memiliki karakteristik berikut:
- Menggunakan typeface Roboto
- Menampilkan aktivitas dalam layar penuh tanpa status bar atau panel tindakan
- Menerapkan latar belakang solid dan hitam
Untuk menerapkan tema Glass, jangan deklarasikan tema dalam Manifes Android Anda.
Jika Anda memiliki gaya kustom untuk komponen Glassware
dan menginginkan tema Glass {i>default<i}
untuk yang lainnya,
mewarisi dari Theme.DeviceDefault
dengan atribut parent
:
<resources>
<style name="CustomTheme" parent="@android:style/Theme.DeviceDefault">
<!-- Theme customization goes here. -->
</style>
</resources>
Lihat panduan developer Android tentang Gaya dan Tema untuk informasi selengkapnya tentang cara membuat tema.
Kartu bergaya kaca
CardBuilder
membuat kartu yang tersusun dengan baik berdasarkan serangkaian properti. Menggunakan tata letak
disediakan oleh CardBuilder.Layout
jika memungkinkan, sehingga konten Anda terlihat dan terasa seperti konten lain di
Kaca.
Untuk menggunakan CardBuilder
:
- Buat instance
CardBuilder
, berikan tata letak yang Anda inginkan dariCardBuilder.Layout
. - Setel properti kartu, seperti teks, catatan kaki, dan stempel waktu.
- Panggil
CardBuilder.getView()
untuk mengonversi kartu ke AndroidView
, atauCardBuilder.getRemoteViews()
untuk mengubahnya menjadiRemoteViews
. - Gunakan
View
dalam aktivitas, tata letak, atauCardScrollView
, atau gunakanRemoteViews
diLiveCard
.
Fitur UI umum
Banyak tata letak yang disediakan oleh CardBuilder
mendukung antarmuka pengguna umum
fitur yang dijelaskan di bawah ini. Lihat dokumentasi masing-masing tata letak di
CardBuilder.Layout
untuk mengetahui daftar fitur yang didukung oleh setiap jenis kartu.
Ikon atribusi
Ikon atribusi adalah ikon piksel 36 × 36 opsional yang muncul di
sudut kanan bawah kartu dan di sebelah kanan tanda waktu. Setel ini
ikon dengan memanggil
CardBuilder.setAttributionIcon()
untuk mengidentifikasi aplikasi Anda, terutama pada
kartu {i>live<i} sehingga pengguna dapat dengan cepat
secara sekilas dan melihat sumber
informasi pada kartu tersebut.
Indikator stack
Indikator tumpukan, dikontrol oleh
CardBuilder.showStackIndicator()
,
adalah lipatan sudut yang muncul di sudut kanan atas sebuah kartu. Gunakan ini sebagai
indikator visual bahwa kartu Anda mewakili seikat kartu lain yang
yang dapat diakses
secara langsung oleh pengguna.
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();
Tata letak
Contoh berikut menunjukkan tata letak yang tersedia menggunakan
CardBuilder
.
TEXT
dan TEXT_FIXED
CardBuilder.Layout.TEXT
tata letak menampilkan teks penuh dari sisi ke sisi dengan
mozaik gambar di latar belakang. Teks berubah ukurannya secara dinamis agar sesuai dengan
atau ukuran ruang yang tersedia.
CardBuilder.Layout.TEXT_FIXED
serupa tetapi memperbaiki teksnya ke ukuran yang lebih kecil.
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
dan COLUMNS_FIXED
Tujuan
CardBuilder.Layout.COLUMNS
yang memperlihatkan mosaik atau ikon pada
sisi kiri kartu dan
teks di sisi kanan. Teks berukuran dinamis
yang paling sesuai dengan
ruang yang tersedia. Untuk menjaga ukuran teks tetap, gunakan
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
Tujuan
CardBuilder.Layout.CAPTION
tata letak memiliki mosaik gambar di latar belakang
dan teks singkat rata di bagian bawah kartu. Ikon juga bisa berupa
ditempatkan di samping teks untuk, misalnya, identitas seseorang
yang terkait dengan konten kartu.
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
Tujuan
CardBuilder.Layout.TITLE
tata letak memiliki mosaik gambar di latar belakang
dengan judul di tengah dan ikon opsional di bagian bawah kartu. Tata letak ini
sering digunakan untuk mewakili
kontak atau target berbagi. Catatan kaki dan stempel waktu
tidak didukung pada tata letak ini.
View view = new CardBuilder(context, CardBuilder.Layout.TITLE)
.setText("TITLE Card")
.setIcon(R.drawable.ic_phone)
.addImage(R.drawable.beach)
.getView();
AUTHOR
Gunakan
CardBuilder.Layout.AUTHOR
tata letak untuk menampilkan pesan atau percakapan
yang fokusnya adalah pada penulis. Alat ini mendukung mosaik gambar di latar belakang,
ikon yang digunakan sebagai avatar penulis, dan {i>heading<i} dan {i>subheading <i}di mana Anda dapat
daftar informasi identifikasi.
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
Tujuan
CardBuilder.Layout.MENU
terlihat seperti menu Glass standar. Alat ini memiliki
ikon dan judul di tengah, dan
catatan kaki opsional. Gunakan tata letak ini untuk
layar konfirmasi (bertransisi dari "Menghapus" menjadi "Dihapus" setelah pengguna
memilih item menu, misalnya). Jika Anda membutuhkan menu yang nyata, Anda harus menggunakan
menu opsi standar.
View view = new CardBuilder(context, CardBuilder.Layout.MENU)
.setText("MENU layout")
.setIcon(R.drawable.ic_phone)
.setFootnote("Optional menu description")
.getView();
EMBED_INSIDE
Tujuan
CardBuilder.Layout.EMBED_INSIDE
menyematkan XML tata letak khusus dari desain Anda sendiri ke dalam Glass
template kartu. Hal ini memungkinkan Anda mendesain UI kustom untuk aplikasi Anda tetapi tetap
penempatan yang benar untuk catatan kaki, stempel waktu, ikon atribusi, dan
indikator tumpukan jika diperlukan.
Setelah menelepon
CardBuilder.getView()
,
penggunaan
findViewById()
pada hasilnya untuk mengakses tampilan di dalam tata letak tersemat Anda. Demikian juga, jika Anda
panggilan telepon
CardBuilder.getRemoteViews()
,
Anda bisa memanipulasi tampilan tata letak tersemat dengan meneruskan ID-nya langsung
ke dalam
RemoteViews
metode penyetel.
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
Untuk contoh yang lebih detail, lihat GitHub Project ApiDemo.
ALERT
Tujuan
CardBuilder.Layout.ALERT
berisi ikon besar
yang berada di tengah dengan
pesan utama dan catatan kaki. Gunakan tata letak ini dalam
Dialog
ke
menampilkan pesan informasi, peringatan, atau error penting di Glassware Anda.
Contoh berikut menunjukkan implementasi AlertDialog
dan menutup
dan membuka setelan Wi-Fi saat pengguna mengetuk kartu:
- Buat class yang memperluas
Dialog
. - Buat kartu menggunakan
CardBuilder
dengan tata letakCardBuilder.Layout.ALERT
, lalu setel tampilan konten dengan kartu ini. (Opsional) Buat
GestureDetector
untuk menangani gestur pengguna di kartu ini.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); } }
(Opsional) Dalam aktivitas Anda, implementasikan
OnClickListener
untuk menangani alur tambahan saat pengguna mengetuk. Untuk mengetahui informasi selengkapnya tentang memulai aktivitas pengaturan seperti Wi-Fi, melihat Memulai setelan.Panggil konstruktor
AlertDialog
untuk menampilkan kartu peringatan.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(); ... } }
Tata letak XML
Berikut adalah dua tata letak kartu dasar yang dapat Anda gunakan jika class CardBuilder melakukan tidak memenuhi kebutuhan Anda.
Tata letak utama
Tata letak ini mendefinisikan padding dan footer standar untuk kartu. Letakkan milik Anda
tampilan dalam RelativeLayout
yang kosong.
<?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>
Tata letak kolom sebelah kiri
Ini menentukan kolom kiri 240 px dan kolom kanan 400 px dalam bentuk dua RelativeLayout
dan Anda dapat menempatkan
tampilan Anda.
<?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>
Dimensi standar
Gunakan file ini bersama dengan tata letak sebelumnya atau tata letak Anda sendiri untuk
untuk mematuhi standar gaya Glass. Buat file ini sebagai
res/values/dimens.xml
di project Android Anda.
<?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>