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

يتناول هذا المستند كيفية اتّباع نمط 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>

الأبعاد العادية

يمكنك استخدام ما يلي مع التنسيقات السابقة أو تنسيقاتك الخاصة لإنشاء ملف يتوافق مع النمط العادي و#39; 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 العادي من موارد مشاريع "استوديو Android". يتيح لك نظام التشغيل 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)
        }
        

    Java

        @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;#39;MENU&quot; و&quot;#39&quot; في الوسط
       على الشاشة ورمز هاتف مجاور.

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

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

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

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