رابط کاربری

این سند به چگونگی پیروی از سبک 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 خالی قرار دهید.

کادر مرکزی با ابعاد ۵۶۰ در ۲۴۰ پیکسل، بیشتر فضای داخلی صفحه را اشغال می‌کند و یک نوار کوچک در پایین آن با ابعاد ۵۶۰ در ۴۰ پیکسل وجود دارد. همچنین چهار بلوک کوچک ۴۰ در ۴۰ پیکسلی وجود دارد که در هر گوشه قرار گرفته‌اند.

در اینجا یک نمونه طرح 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 تعریف می‌کند که می‌توانید نماهای خود را در آنها قرار دهید. برای مشاهده مثال به تصویر زیر مراجعه کنید.

یک ستون سمت چپ با ابعاد ۲۴۰ در ۳۶۰ پیکسل نشان می‌دهد که طرح اصلی را به جلو هل می‌دهد.  اندازه آن برای جا شدن فشرده می‌شود، ناحیه اصلی ۳۳۰ در ۲۴۰ پیکسل است، با یک نوار کوچک پایین  که ۳۳۰ در ۴۰ پیکسل است. دو گوشه سمت راست دارای دو کادر کوچک ۴۰ در ۴۰ پیکسلی هستند و  چهار کادر ۳۰ در ۴۰ پیکسلی دیگر وجود دارد، دو کادر در گوشه‌های پایین ستون سمت چپ  و دو کادر در سمت چپ طرح اصلی، یکی در بالا و یکی در پایین.

در اینجا یک نمونه طرح 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 در پروژه اندروید خود ایجاد کنید.

<?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 استفاده کنید. آن‌ها باید بر اساس فایل استاندارد منوی اندروید از منابع پروژه اندروید استودیو باشند. اندروید به شما این امکان را می‌دهد که ایجاد منوی استاندارد را لغو کرده و آن را با پیاده‌سازی خود جایگزین کنید. برای انجام این کار، این مراحل را دنبال کنید:

  1. طرح‌بندی را با RecyclerView ایجاد کنید و آن را به عنوان نمای Activity خود تنظیم کنید.
  2. RecyclerView و آداپتور آن را طوری تنظیم کنید که از مجموعه جدید ایجاد شده از آیتم‌های منو استفاده کنند.
  3. متد onCreateOptionsMenu را بازنویسی (override) کنید.
    1. منوی خود را پر کنید و عنصر جدید خود را برای هر مورد از منو به مجموعه اضافه کنید.
    2. متد notifyDataSetChanged را روی آداپتور فراخوانی کنید.

    کاتلین

        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 را در فرگمنت یا اکتیویتی فراخواننده، بازنویسی (Override) کنید.

دستورالعمل‌ها

در زیر لیستی از پیشنهادات برای نحوه تنظیم طرح بندی منو شما ارائه شده است:

تصویر زیر نمونه‌ای از طرح‌بندی منوی سفارشی است:

این تصویر ساده، یک پس‌زمینه سیاه با عبارت «طرح منو» در مرکز صفحه و یک نماد تلفن در مجاورت آن را نشان می‌دهد.

برای جزئیات پیاده‌سازی ، برنامه نمونه کارت را بررسی کنید.

صفحات قابل کشیدن

نمایشگر گلس و تاچ‌پد با هم کار می‌کنند تا کارت‌های قابل کشیدن را به روشی راحت نمایش دهند. می‌توانید صفحات قابل کشیدن را در activity خود با API استاندارد ViewPager اندروید بسازید.

برای اطلاعات بیشتر در مورد نحوه استفاده از Android ViewPager برای پیمایش کارت‌ها یا صفحات، به مستندات آموزشی Screen slide مراجعه کنید.