واجهة المستخدم

يتناول هذا المستند كيفية اتّباع تصميم Glass وتنفيذ أفضل الممارسات الشائعة لواجهة المستخدم التي يمكنها تحسين تجربة المستخدم. وتشمل عناصر واجهة المستخدم التالية:

المظهر

يتميّز مظهر Glass الذي نقترح استخدامه بما يلي:

  • تعرض الأنشطة بملء الشاشة بدون شريط إجراءات.
  • تطبيق خلفية سوداء خالصة
  • تضبط هذه السمة اللون الأفتح لتأثير حافة اللون.
  • تطبيق لون نص أبيض

في ما يلي إعدادات المظهر المقترَحة لـ 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>

تنسيقات XML

في ما يلي تخطيطا البطاقات الأساسيان اللذان يمكن أن تضخّمهما الأجزاء:

التصميم الرئيسي

يحدّد هذا التصميم الحاشية السفلية والحاشية العادية المقترَحة للبطاقة. أدخِلوا آراءكم في FrameLayout الفارغ.

يشغل المربّع الأوسط معظم المساحة الداخلية للشاشة بمقاس 560 × 240 بكسل، مع شريط صغير في الأسفل بمقاس 560 × 40 بكسل.
          هناك أيضًا أربع مربّعات صغيرة بحجم 40 × 40 بكسل، واحد في كل زاوية

في ما يلي مثال على تنسيق 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>

تصميم العمود الأيمن

يحدّد هذا التصميم عمودًا أيسر بعرض الثلث وعمودًا أيمن بعرض الثلثين في شكل فئتَين FrameLayout يمكنك وضع طرق العرض فيهما. يُرجى الاطّلاع على الصورة التالية للاطّلاع على مثال.

تعرض هذه السمة عمودًا على اليمين بحجم 240 × 360 بكسل، ما يؤدي إلى إزاحة التنسيق الرئيسي.
          يتم تصغير حجمها لتناسب المساحة المخصّصة لها، وتبلغ مساحتها الرئيسية 330 × 240 بكسل، مع شريط صغير في الأسفل يبلغ حجمه 330 × 40 بكسل. في الزاويتين اليمنى العلوية والسفلية، يظهر مربّعان صغيران بحجم 40 × 40 بكسل،
          وهناك أربعة مربّعات أخرى بحجم 30 × 40 بكسل، اثنان في الزاويتين السفليتين من العمود الأيمن
          واثنان على الجانب الأيمن من التصميم الرئيسي، أحدهما في الأعلى والآخر في الأسفل.

في ما يلي مثال على تنسيق 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>

السمات العادية

استخدِم ما يلي مع التنسيقات السابقة أو تنسيقاتك الخاصة لإنشاء ملف يتوافق مع نمط Glass العادي. أنشئ هذا الملف باسم res/values/dimens.xml في مشروع 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>

ننصحك باستخدام RecyclerView لإنشاء القوائم. ويجب أن تستند إلى ملف قائمة Android العادي من موارد مشروع &quot;استوديو Android&quot;. يتيح لك نظام التشغيل Android إلغاء إنشاء القائمة العادية واستبدالها بتنفيذك. ولإجراء ذلك، اتبع الخطوات التالية:

  1. أنشئ التنسيق باستخدام RecyclerView واضبطه كطريقة العرض الخاصة بـ Activity.
  2. اضبط RecyclerView والمحوّل الخاص به لاستخدام مجموعة عناصر القائمة التي تم إنشاؤها حديثًا.
  3. تجاوز طريقة onCreateOptionsMenu.
    1. وسِّع قائمتك وأضِف العنصر الجديد إلى المجموعة لكل عنصر في القائمة.
    2. استدعِ طريقة notifyDataSetChanged في المحوّل.

    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)
        }
        

    جافا

        @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);
        }
        
  4. استخدِم OnScrollListener مع LayoutManager و SnapHelper لتحديد الخيار الذي تم اختياره.
  5. استمع إلى إيماءة TAP للتعامل مع حدث اختيار عنصر القائمة.
  6. أنشئ Intent يتضمّن معلومات حول عنصر القائمة المحدّد.
  7. اضبط نتيجة لهذا النشاط وأنهِهِ.
  8. استدعِ الدالة startActivityForResult من الجزء أو النشاط الذي تريد أن تظهر فيه القائمة. استخدِم إيماءة TAP لهذا الغرض.
  9. تجاوز onActivityResult في الجزء أو النشاط الذي يتم استدعاؤه للتعامل مع عنصر القائمة المحدّد.

الإرشادات

في ما يلي قائمة باقتراحات حول كيفية إعداد تخطيط القائمة:

الصورة التالية هي مثال على تخطيط قائمة مخصّص:

تعرض هذه الصورة البسيطة خلفية سوداء مع عبارة &quot;تنسيق القائمة&quot; في وسط الشاشة ورمز هاتف بجانبها.

راجِع تطبيق عيّنة البطاقة للاطّلاع على تفاصيل التنفيذ.

صفحات قابلة للتمرير السريع

تعمل شاشة Glass ولوحة اللمس معًا لعرض البطاقات التي يمكن التمرير بينها بطريقة ملائمة. يمكنك إنشاء صفحات قابلة للتمرير في نشاطك باستخدام واجهة برمجة التطبيقات ViewPager العادية في Android.

يمكنك الانتقال إلى مستندات التدريب الخاصة بميزة التمرير السريع على الشاشة للحصول على مزيد من المعلومات حول كيفية استخدام ViewPager في Android للتنقّل بين البطاقات أو الشاشات.