Kart Tasarımı

Bu dokümanda, Glass stilini nasıl takip edeceğiniz açıklanmaktadır ve GDK'yı kullanırken yaygın kullanıcı arayüzü en iyi uygulamalarını benimseyin.

Cam teması

Glass, Glassware'inize standart bir tema uyguladığından kullanıcı arayüzünün geri kalanıyla tutarlı kalmasını sağlar. İlgili içeriği oluşturmak için kullanılan tema aşağıdaki özelliklere sahiptir:

  • Roboto yazı karakteri kullanıyor
  • Etkinlikleri durum çubuğu veya işlem çubuğu olmadan tam ekran olarak gösterir
  • Düz, siyah arka plan uygulanır

Glass temasını uygulamak için Android Manifest'inizde tema beyan etmeyin.

Cam eşyanızın parçaları için özel bir stiliniz varsa ve diğer her şey için varsayılan Google Glass temasını istiyorsanız parent özelliğiyle Theme.DeviceDefault öğesinden devralın:

<resources>
    <style name="CustomTheme" parent="@android:style/Theme.DeviceDefault">
        <!-- Theme customization goes here. -->
    </style>
</resources>

Şu konudaki Android geliştirici kılavuzuna bakın: Stiller ve Temalar konusuna bakın.

Cam tarzı kartlar

CardBuilder sınıfı, bir dizi özellik göz önünde bulundurulduğunda iyi biçimli kartlar oluşturur. Düzenleri kullanın sağlayan: CardBuilder.Layout içeriğinizin diğer içerikler gibi görünmesi için mümkün olduğunca Bardak.

CardBuilder uygulamasını kullanmak için:

  1. CardBuilder öğesinin bir örneğini oluşturun ve ona istediğiniz düzeni verin CardBuilder.Layout
  2. Kart özelliklerini (ör. metin, dipnot ve zaman damgası) ayarlayın.
  3. CardBuilder.getView() numaralı telefonu arayın kartı Android'e dönüştürmek için View veya CardBuilder.getRemoteViews() dönüştürmek için RemoteViews nesnesini tanımlayın.
  4. View öğesini etkinliklerinizde, düzenlerinizde veya bir CardScrollView veya LiveCard içinde RemoteViews.

Genel kullanıcı arayüzü özellikleri

CardBuilder tarafından sağlanan düzenlerin çoğu, ortak kullanıcı arayüzünü destekler. özelliklerini inceleyin. Her düzenle ilgili dokümanlar için bkz. CardBuilder.Layout inceleyebilirsiniz.

İlişkilendirme simgesi

Atıf simgesi, zaman damgasının sağ alt köşesinde görebilirsiniz. Bunu ayarla sesli arama yaparak simge CardBuilder.setAttributionIcon() özellikle canlı kartlarda uygulamanızı tanımlamak, böylece kullanıcının karttaki bilgilerin kaynağına göz atmayı unutmayın.

Yığın göstergesi

Kontrol grubu tarafından kontrol edilen CardBuilder.showStackIndicator() kartın sağ üst köşesinde görünen bir köşeden kıvrımdır. Bunu şu şekilde kullan: kartınızın başka bir kart paketini temsil ettiğini gösteren, tek bir yerden ulaşmak mümkün.

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();

Düzenler

Aşağıdaki örneklerde CardBuilder

TEXT ve TEXT_FIXED

CardBuilder.Layout.TEXT düzen isteğe bağlı olarak tam çerçeve metin gösteriyor arka planda bir resim mozaiği var. Metin, sayfaya en iyi sığacak şekilde dinamik olarak yeniden boyutlandırılır kullanılabilir alan. CardBuilder.Layout.TEXT_FIXED benzer ancak metnini daha küçük bir boyuta sabitler.

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 ve COLUMNS_FIXED

İlgili içeriği oluşturmak için kullanılan CardBuilder.Layout.COLUMNS sayfa düzeninde bir resim mozaiği veya simge kartın sol tarafında, metin de sağ tarafta. Metin dinamik olarak boyutlandırılır bir dizi belgeyi kullanabilirsiniz. Metin boyutunu sabit tutmak için 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

İlgili içeriği oluşturmak için kullanılan CardBuilder.Layout.CAPTION düzenin arka planında bir resim mozaiği var ve kartın alt kısmına hizalanan kısa açıklama metni. Simge ayrıca Bir kişinin kimliğini temsil edecek şekilde altyazının yanına yerleştirilir kart içeriğiyle ilişkilendirilmiştir.

Şekil 1: (arka plan resmi photoeverywhere.co.uk, kırpılmış)
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

İlgili içeriği oluşturmak için kullanılan CardBuilder.Layout.TITLE düzenin arka planında bir resim mozaiği var ortalanmış bir başlık ve kartın alt kısmında isteğe bağlı bir simge gösterilir. Bu düzen genellikle kişileri temsil etmek veya hedefleri paylaşmak için kullanılır. Dipnot ve zaman damgası bu düzende desteklenmiyor.

View view = new CardBuilder(context, CardBuilder.Layout.TITLE)
    .setText("TITLE Card")
    .setIcon(R.drawable.ic_phone)
    .addImage(R.drawable.beach)
    .getView();

AUTHOR

Şunu kullanın: CardBuilder.Layout.AUTHOR bir mesaj veya ileti dizisi görüntüleyecek düzen yazarın odak noktasıdır. Arka planda bir resim mozaiği kullanılmasını destekler. yazarın avatarı olarak kullanılan bir simge ve doğrudan ve tanımlayıcı bilgileri listelemek.

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();

İlgili içeriği oluşturmak için kullanılan CardBuilder.Layout.MENU görünüm standart bir Glass menüsüne benzer. İçinde ortalanmış bir simge, başlık ve isteğe bağlı bir dipnot. Bu düzeni şunlar için kullanın: onay ekranları (kullanıcı sonrasında "Siliniyor"dan "Silindi"ye geçiş Kullanıcı örneğin bir menü seçeneğini seçtiğinde). Gerçek bir menüye ihtiyacınız varsa standart seçenekler menüsünü kullanın.

View view = new CardBuilder(context, CardBuilder.Layout.MENU)
    .setText("MENU layout")
    .setIcon(R.drawable.ic_phone)
    .setFootnote("Optional menu description")
    .getView();

EMBED_INSIDE

İlgili içeriği oluşturmak için kullanılan CardBuilder.Layout.EMBED_INSIDE düzen, standart Glass'a kendi tasarımınızın özel bir düzen XML'sini yerleştirir kart şablonu. Bu, uygulamanız için özel bir kullanıcı arayüzü tasarlamanıza, bir kartın dipnotu, zaman damgası, ilişkilendirme simgesi ve yığın göstergesini kullanın.

Aradıktan sonra CardBuilder.getView() kullan findViewById() sonuç simgesini tıklayın. Aynı şekilde telefon etmek CardBuilder.getRemoteViews() kimliklerini doğrudan ileterek yerleşik düzeninizin görünümlerini değiştirebilirsiniz. içine RemoteViews belirleyici yöntemlerdir.

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

Daha ayrıntılı bir örnek için GitHub ApiDemo projesi

ALERT

İlgili içeriği oluşturmak için kullanılan CardBuilder.Layout.ALERT düzende, içinde birincil ileti ve dipnottur. Bu düzeni bir Dialog - Glassware'inizde önemli bir bilgilendirme mesajı, uyarı veya hata gösterir.

Aşağıdaki örnekte bir AlertDialog uygulaması gösterilmektedir ve kartı ve kullanıcı karta dokunduğunda kablosuz ayarlarını açar:

  1. Dialog kapsamını genişleten bir sınıf oluşturun.
  2. CardBuilder kodunu CardBuilder.Layout.ALERT düzeniyle oluşturun ve ardından bu kartla içerik görünümünü ayarlayın.
  3. (İsteğe bağlı) Bu karttaki kullanıcı hareketlerini işlemek için bir GestureDetector oluşturun.

    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);
        }
    }
    
  4. (İsteğe bağlı) Etkinliğinizde OnClickListener kullanıcı dokunduğunda ek akışlar işler. Daha fazla bilgi için kablosuz gibi ayar etkinlikleri başlatılıyor, bkz. Başlangıç ayarları.

  5. Uyarı kartını görüntülemek için AlertDialog oluşturucuyu çağırın.

    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();
    
            ...
        }
    }
    

XML düzenleri

CardBuilder sınıfının kullandığı iki temel kart düzenini kullanabilirsiniz. bir yöntem de yoktur.

Ana düzen

Bu düzen, bir kart için standart dolguyu ve altbilgiyi tanımlar. Kendinizinkini görüntüleme sayısı: boş 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>

Sol sütun düzeni

Bu, iki RelativeLayout biçiminde 240 piksel sol ve 400 piksel sağ sütunu tanımlar videolar da hazırlar.

<?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>

Standart boyutlar

Bu dosyayı önceki düzenlerle veya kendi düzenlerinizle birlikte kullanarak standart Glass stiline uymasını sağlar. Bu dosyayı şu şekilde oluştur: res/values/dimens.xml.

<?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>