طراحی واکنش‌گرا/تطبیقی با نماها

امتحان کردن روش Compose
Jetpack Compose جعبه‌ابزار واسط کاربر توصیه‌شده برای Android است. با نحوه کار با چیدمان‌های واکنش‌گرا در Compose آشنا شوید.

چیدمان‌های واکنش‌گرا/تطبیقی تجربه کاربری بهینه‌شده‌ای را بدون توجه به اندازه صفحه‌نمایش ارائه می‌دهند. چیدمان‌های واکنش‌گرا/تطبیقی را پیاده‌سازی کنید تا برنامه مبتنی بر نمای شما بتواند از همه اندازه‌ها، جهت‌ها، و پیکربندی‌های نمایشگر، ازجمله پیکربندی‌های قابل‌تغییر اندازه مثل حالت چندپنجره‌ای، پشتیبانی کند.

طراحی تعاملی

اولین گام در پشتیبانی از انواع مختلف ضریب‌های شکل دستگاه، ایجاد چیدمانی است که به تغییرات مقدار فضای نمایش دردسترس برای برنامه‌تان واکنش‌گرا باشد.

ConstraintLayout

بهترین راه برای ایجاد چیدمان واکنش‌گرا استفاده از ConstraintLayout به‌عنوان چیدمان پایه برای میانای کاربری است. ConstraintLayout به شما امکان می‌دهد موقعیت و اندازه هر نما را براساس روابط فضایی با سایر نماها در چیدمان مشخص کنید. سپس همه نماها می‌توانند با تغییر فضای نمایش، باهم جابه‌جا شوند و تغییر اندازه دهند.

آسان‌ترین راه برای ساختن چیدمان با ConstraintLayout، استفاده از «ویرایشگر چیدمان» در «استودیو Android» است. «ویرایشگر چیدمان» به شما امکان می‌دهد نماهای جدید را به چیدمان بکشید، محدودیت‌های مربوط به نماهای والد و هم‌نیا را اعمال کنید، و ویژگی‌های نما را تنظیم کنید—همه این کارها بدون ویرایش دستی XML انجام می‌شود.

شکل ۳. «ویرایشگر چیدمان» در «استودیو Android» که ConstraintLayout را نشان می‌دهد.

برای اطلاعات بیشتر، ساختن واسط کاربر واکنش‌گرا با ConstraintLayout را ببینید.

عرض و ارتفاع واکنش‌گرا

برای اطمینان از اینکه چیدمان شما به اندازه‌های مختلف نمایش واکنش نشان می‌دهد، از wrap_content، match_parent، یا 0dp (match constraint) برای عرض و ارتفاع مؤلفه‌های نما به‌جای مقادیر کدگذاری‌شده استفاده کنید:

  • wrap_content: نما اندازه خود را طوری تنظیم می‌کند که با محتوای موجود در نما مطابقت داشته باشد.
  • ‫match_parent: نما تا حد امکان در نمای والد گسترش می‌یابد.
  • 0dp (match constraint): در ConstraintLayout، شبیه به match_parent. این نما همه فضای دردسترس را در چارچوب محدودیت‌های نما اشغال می‌کند.

برای مثال:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/lorem_ipsum" />

شکل ۴ نشان می‌دهد که چگونه عرض و ارتفاع TextView با تغییر عرض نمایشگر براساس جهت دستگاه تنظیم می‌شود.

شکل ۴. TextView پاسخگو.

TextView عرض خود را طوری تنظیم می‌کند که تمام فضای دردسترس را پر کند (match_parent) و ارتفاع آن دقیقاً به همان اندازه فضایی است که ارتفاع نوشتار موجود نیاز دارد (wrap_content)، که به نما امکان می‌دهد با ابعاد مختلف نمایشگر و مقادیر مختلف نوشتار سازگار شود.

اگر از LinearLayout استفاده می‌کنید، می‌توانید نماهای فرزند را براساس وزن چیدمان ازهم باز کنید تا نماها به‌طور متناسب فضای دردسترس را پر کنند. بااین‌حال، استفاده از وزن‌ها در LinearLayout تودرتو مستلزم این است که سیستم چندین بار چیدمان را اجرا کند تا اندازه هر نما را تعیین کند، که این امر عملکرد واسط کاربر را کند می‌کند.

ConstraintLayout می‌تواند تقریباً همه چیدمان‌های ممکن با LinearLayout را بدون تأثیر بر عملکرد ایجاد کند، بنابراین LinearLayout تودرتو را به ConstraintLayout تبدیل کنید. سپس می‌توانید چیدمان‌های وزنی را با زنجیره‌های محدودیت تعریف کنید.

طراحی تطبیقی

چیدمان برنامه‌تان باید همیشه نسبت‌به اندازه‌های مختلف نمایشگر واکنش‌گرا باشد. بااین‌حال، حتی یک چیدمان واکنش‌گرا هم نمی‌تواند بهترین تجربه کاربری را در هر دستگاه یا نمایشگر حالت چندپنجره‌ای ارائه دهد. برای مثال، واسط کاربری‌ای که برای تلفن طراحی کرده‌اید احتمالاً تجربه کاربری بهینه‌ای در رایانه لوحی ارائه نمی‌دهد. طراحی تطبیقی چیدمان‌های جایگزینی ارائه می‌دهد که برای ابعاد مختلف نمایشگر بهینه‌سازی شده‌اند.

SlidingPaneLayout برای واسط‌های کاربر تفصیلی-فهرستی

میانای کاربری فهرست-جزئیات معمولاً تجربه کاربری متفاوتی در صفحه‌نمایش‌های با اندازه‌های مختلف ارائه می‌دهد. در صفحه‌نمایش‌های بزرگ، قاب‌های فهرست و جزئیات معمولاً کنار هم قرار دارند. وقتی موردی در فهرست انتخاب می‌شود، اطلاعات مورد در قاب جزئیات نمایش داده می‌شود بدون اینکه واسط کاربر تغییر کند—دو قاب در کنار یکدیگر باقی می‌مانند. اما در صفحه‌نمایش‌های کوچک، دو قاب به‌صورت جداگانه نمایش داده می‌شوند و هر قاب کل فضای نمایش را اشغال می‌کند. وقتی موردی در قاب فهرست انتخاب می‌شود، قاب جزئیات (که حاوی اطلاعات مورد انتخاب‌شده است) جایگزین قاب فهرست می‌شود. پیمایش به عقب، بخش جزئیات را با فهرست جایگزین می‌کند.

SlidingPaneLayout منطق تعیین اینکه کدام‌یک از دو تجربه کاربری برای اندازه پنجره فعلی مناسب است را مدیریت می‌کند:

<?xml version="1.0" encoding="utf-8"?>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/item_navigation" />

</androidx.slidingpanelayout.widget.SlidingPaneLayout>

مشخصه‌های layout_width و layout_weight دو نمای موجود در SlidingPaneLayout رفتار SlidingPaneLayout را تعیین می‌کنند. در این مثال، اگر پنجره به‌اندازه کافی بزرگ باشد (حداقل ۵۸۰dp عرض) تا هر دو نما را نمایش دهد، قاب‌ها کنار هم نمایش داده می‌شوند. اما اگر عرض پنجره کمتر از ۵۸۰ واحد مستقل از تراکم باشد، قاب‌ها روی یکدیگر می‌لغزند تا به‌طور جداگانه کل پنجره برنامه را اشغال کنند.

اگر عرض پنجره بزرگ‌تر از کل حداقل عرض مشخص‌شده (۵۸۰dp) باشد، می‌توان از مقادیر layout_weight برای اندازه‌بندی دو قاب به‌صورت متناسب استفاده کرد. در مثال، قاب فهرست همیشه ۲۸۰dp عرض دارد زیرا وزن ندارد. بااین‌حال، پانل جزئیات همیشه هر فضای افقی فراتر از ۵۸۰dp را به‌دلیل تنظیمات layout_weight نما پر می‌کند.

منابع چیدمان جایگزین

برای تطبیق دادن طراحی میانای کاربر با اندازه‌های نمایشگر بسیار متفاوت، از چیدمان‌های جایگزین مشخص‌شده با توصیف‌گرهای منبع استفاده کنید.

شکل ۵. برنامه یکسان بااستفاده از چیدمان‌های مختلف برای اندازه‌های نمایشگر مختلف.

با ایجاد کردن دایرکتوری‌های res/layout/ اضافی در کد منبع برنامه‌تان، می‌توانید چیدمان‌های تطبیقی و مختص صفحه‌نمایش ارائه دهید. برای هر پیکربندی صفحه که به چیدمان متفاوتی نیاز دارد، یک دایرکتوری ایجاد کنید. سپس توصیف‌گر پیکربندی صفحه را به نام دایرکتوری layout اضافه کنید (برای مثال، layout-w600dp برای صفحه‌هایی که عرض دردسترس آن‌ها ۶۰۰ پیکسل مستقل از تراکم است).

توصیف‌گرهای پیکربندی نشان‌دهنده فضای نمایش نمایان دردسترس برای رابط کاربری برنامه شما است. سیستم هنگام انتخاب چیدمان برای برنامه شما، هرگونه تزئینات سیستم (مانند نوار پیمایش) و تغییرات پیکربندی پنجره (مانند حالت چندپنجره‌ای) را درنظر می‌گیرد.

برای ایجاد چیدمان‌های جایگزین در Android Studio، به استفاده از انواع چیدمان برای بهینه‌سازی برای صفحه‌نمایش‌های مختلف در توسعه میانای کاربر با «نماها» مراجعه کنید.

کوچک‌ترین توصیف‌کننده عرض

واجدشرایط اندازه صفحه کوچک‌ترین عرض به شما امکان می‌دهد چیدمان‌های جایگزین برای نمایشگرهایی که حداقل عرض آن‌ها برحسب پیکسل‌های مستقل از تراکم (dp) اندازه‌گیری می‌شود ارائه دهید.

با توصیف اندازه صفحه‌نمایش به‌عنوان معیاری از dp،‏ Android به شما امکان می‌دهد چیدمان‌هایی ایجاد کنید که برای ابعاد نمایشگر خاصی طراحی شده‌اند، بدون اینکه نگران تراکم‌های پیکسلی مختلف باشید.

برای مثال، می‌توانید با ایجاد نسخه‌های مختلف فایل در دایرکتوری‌های مختلف، چیدمانی به‌نام main_activity ایجاد کنید که برای تلفن‌ها و رایانه‌های لوحی بهینه‌سازی شده است:

res/layout/main_activity.xml           # For phones (smaller than 600dp smallest width)
res/layout-sw600dp/main_activity.xml   # For 7" tablets (600dp wide or wider)

توصیف‌کننده کوچک‌ترین عرض، کوچک‌ترین سمت از دو سمت نمایشگر را مشخص می‌کند، صرف‌نظر از جهت فعلی دستگاه، بنابراین راهی برای مشخص کردن اندازه کلی نمایشگر دردسترس برای چیدمان شما است.

در اینجا نحوه مطابقت سایر مقادیر کوچک‌ترین عرض با اندازه‌های معمول صفحه‌نمایش آورده شده است:

  • ‫۳۲۰dp: صفحه تلفن کوچک (‎۲۴۰x۳۲۰ ldpi،‏ ‎۳۲۰x۴۸۰ mdpi،‏ ‎۴۸۰x۸۰۰ hdpi، و غیره)
  • ‫۴۸۰dp: صفحه‌نمایش تلفن بزرگ ~۵ اینچ (۴۸۰x۸۰۰ mdpi)
  • ‫۶۰۰dp: رایانه لوحی ۷ اینچی (۶۰۰x۱۰۲۴ mdpi)
  • ‫۷۲۰dp: رایانه لوحی ۱۰ اینچی (۷۲۰x۱۲۸۰ mdpi،‏ ۸۰۰x۱۲۸۰ mdpi، و غیره)

شکل زیر نمای دقیق‌تری از نحوه مطابقت عرض‌های مختلف dp صفحه‌نمایش با اندازه‌ها و جهت‌های مختلف صفحه‌نمایش ارائه می‌دهد.

شکل ۶. نقطه‌های شکست عرض توصیه‌شده برای پشتیبانی از اندازه‌های مختلف صفحه‌نمایش.

مقادیر برای واجدشرایط کوچک‌ترین عرض dp است، زیرا آنچه اهمیت دارد مقدار فضای نمایش دردسترس پس‌از محاسبه تراکم پیکسل توسط سیستم است (نه وضوح پیکسل خام).

اندازه‌هایی که بااستفاده از توصیف‌گرهای منبع مانند کوچک‌ترین عرض مشخص می‌کنید اندازه‌های واقعی صفحه‌نمایش نیستند. بلکه اندازه‌ها عرض یا ارتفاع را برحسب واحد dp که برای پنجره برنامه‌تان دردسترس است مشخص می‌کنند. سیستم Android ممکن است از بخشی از صفحه برای واسط کاربر سیستم (مانند نوار سیستم در پایین صفحه یا نوار وضعیت در بالا) استفاده کند، بنابراین ممکن است بخشی از صفحه برای چیدمان شما دردسترس نباشد. اگر از برنامه‌تان در حالت چندپنجره‌ای استفاده می‌شود، برنامه فقط به اندازه پنجره‌ای که برنامه را دربرمی‌گیرد دسترسی دارد. وقتی اندازه پنجره تغییر می‌کند، تغییر پیکربندی با اندازه پنجره جدید راه‌اندازی می‌شود که به سیستم امکان می‌دهد فایل چیدمان مناسب را انتخاب کند. بنابراین، اندازه‌های توصیف‌گر منبعی که اعلام می‌کنید باید فقط فضای موردنیاز برنامه‌تان را مشخص کند. سیستم هنگام ارائه فضا برای چیدمان شما، هر فضایی را که توسط واسط کاربر سیستم استفاده می‌شود درنظر می‌گیرد.

توصیف‌کننده عرض دردسترس

Instead of changing the layout based on the smallest width of the display, you might want to change your layout based on how much width or height is available. برای مثال، ممکن است بخواهید هر زمان که صفحه حداقل ۶۰۰dp عرض دارد، از چیدمان دوصفحه‌ای استفاده کنید، که ممکن است بسته به اینکه دستگاه در جهت افقی یا عمودی باشد، تغییر کند. در این حالت، باید از توصیف‌کننده عرض دردسترس به‌صورت زیر استفاده کنید:

res/layout/main_activity.xml         # For phones (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml  # For 7" tablets or any screen with 600dp available width
                                     # (possibly landscape phones)

اگر ارتفاع دردسترس برای برنامه‌تان مهم است، می‌توانید از واجدشرایط ارتفاع دردسترس استفاده کنید. برای مثال، layout-h600dp برای صفحه‌نمایش‌هایی با حداقل ۶۰۰ پیکسل مستقل از تراکم ارتفاع صفحه‌نمایش.

توصیف‌کننده‌های جهت

اگرچه ممکن است بتوانید از همه انواع اندازه فقط بااستفاده از ترکیب‌های واجدشرایط کوچک‌ترین عرض و عرض دردسترس پشتیبانی کنید، شاید بخواهید تجربه کاربری را نیز وقتی کاربر بین جهت‌های عمودی و افقی جابه‌جا می‌شود تغییر دهید.

برای این کار، می‌توانید واژه‌های توصیفی port یا land را به نام‌های دایرکتوری چیدمانتان اضافه کنید. فقط مطمئن شوید که واجدشرایط‌های جهت‌یابی بعداز واجدشرایط‌های اندازه قرار بگیرند. برای مثال:

res/layout/main_activity.xml                # For phones
res/layout-land/main_activity.xml           # For phones in landscape
res/layout-sw600dp/main_activity.xml        # For 7" tablets
res/layout-sw600dp-land/main_activity.xml   # For 7" tablets in landscape

برای اطلاعات بیشتر درباره همه توصیف‌گرهای پیکربندی صفحه، به نمای کلی منابع برنامه مراجعه کنید.

کلاس‌های اندازه پنجره

کلاس‌های اندازه پنجره نقاط شکست نمای هدف هستند که به شما کمک می‌کنند چیدمان‌های تطبیقی ایجاد کنید. نقاط شکست، ناحیه نمایش دردسترس برای برنامه‌تان را به‌صورت فشرده، متوسط، یا گسترده شناسایی می‌کنند. عرض و ارتفاع به‌طور جداگانه مشخص می‌شوند، بنابراین برنامه شما همیشه یک کلاس اندازه پنجره برای عرض و یک کلاس اندازه پنجره برای ارتفاع دارد.

برای اعمال چیدمان‌های تطبیقی به‌صورت برنامه‌ریزی‌شده، کارهای زیر را انجام دهید:

  • ایجاد منابع چیدمان براساس نقاط شکست کلاس اندازه پنجره
  • کلاس‌های اندازه پنجره عرض و ارتفاع برنامه‌تان را بااستفاده از تابع WindowSizeClass#compute() از کتابخانه Jetpack WindowManager محاسبه کنید
  • منبع چیدمان را برای کلاس‌های اندازه پنجره فعلی گسترش دهید

برای اطلاعات بیشتر، به کلاس‌های اندازه پنجره مراجعه کنید.

عناصر واسط کاربر مدولارشده بااستفاده از قطعه‌ها

هنگام طراحی برنامه برای اندازه‌های مختلف نمایشگر، از قطعه‌ها برای استخراج منطق میانای کاربر در مؤلفه‌های جداگانه استفاده کنید تا مطمئن شوید که رفتار میانای کاربر را بی‌دلیل در فعالیت‌ها تکرار نمی‌کنید. سپس می‌توانید قطعه‌ها را ترکیب کنید تا طرح‌بندی‌های چندقاب در صفحه‌نمایش‌های بزرگ ایجاد کنید، یا می‌توانید قطعه‌ها را در فعالیت‌های جداگانه در صفحه‌نمایش‌های کوچک قرار دهید.

برای مثال، الگوی فهرست-جزئیات (به SlidingPaneLayout در بالا مراجعه کنید) می‌تواند با یک تکه حاوی فهرست و تکه دیگری حاوی جزئیات مورد فهرست پیاده‌سازی شود. در صفحه‌نمایش‌های بزرگ، قطعه‌ها می‌توانند کنار هم نمایش داده شوند؛ در صفحه‌نمایش‌های کوچک، به‌صورت تکی و با پر کردن صفحه.

برای کسب اطلاعات بیشتر، نمای کلی قطعه‌ها را ببینید.

جاسازی کردن فعالیت

اگر برنامه‌تان از چند فعالیت تشکیل شده است، جاسازی فعالیت به شما امکان می‌دهد به‌راحتی یک واسط کاربر تطبیقی ایجاد کنید.

جاسازی فعالیت چندین فعالیت یا چندین نمونه از یک فعالیت را به‌طور هم‌زمان در پنجره تکلیف برنامه نمایش می‌دهد. در صفحه‌نمایش‌های بزرگ، فعالیت‌ها می‌توانند کنار هم نمایش داده شوند؛ در صفحه‌نمایش‌های کوچک، روی هم قرار می‌گیرند.

با ایجاد فایل پیکربندی XML، نحوه نمایش فعالیت‌های برنامه‌تان را تعیین می‌کنید و سیستم از این فایل برای تعیین ارائه مناسب براساس اندازه نمایشگر استفاده می‌کند. به‌جای‌آن، می‌توانید تماس‌های Jetpack WindowManager API برقرار کنید.

جاسازی فعالیت از تغییر جهت دستگاه و دستگاه‌های تاشو پشتیبانی می‌کند، و با چرخاندن یا تا کردن و باز کردن دستگاه، فعالیت‌ها را روی هم قرار می‌دهد یا از هم جدا می‌کند.

برای اطلاعات بیشتر، به جاسازی فعالیت مراجعه کنید.

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

برنامه‌تان را در اندازه‌های مختلف صفحه‌نمایش و نسبت‌های ابعادی آزمایش کنید تا مطمئن شوید میانای کاربر به‌درستی مقیاس‌بندی می‌شود.

Android 10 (سطح میانای برنامه‌سازی کاربردی ۲۹) و بالاتر از طیف وسیعی از نسبت‌های ابعادی پشتیبانی می‌کنند. ضریب‌های شکل تاشو می‌توانند از صفحه‌نمایش‌های بلند و باریک، مانند ۲۱:۹ در حالت تاشده، تا نسبت ابعادی مربعی ۱:۱ در حالت بازشده متفاوت باشند.

برای اطمینان از سازگاری با بیشترین تعداد دستگاه ممکن، برنامه‌هایتان را برای بیشترین تعداد ممکن از نسبت‌های ابعادی صفحه زیر آزمایش کنید:

شکل ۷. نسبت‌های ابعادی مختلف صفحه‌نمایش.

اگر به دستگاه‌هایی با اندازه‌های مختلف صفحه‌نمایش که می‌خواهید آزمایش کنید دسترسی ندارید، می‌توانید از شبیه‌ساز Android برای شبیه‌سازی تقریباً هر اندازه صفحه‌نمایشی استفاده کنید.

اگر ترجیح می‌دهید روی دستگاه واقعی آزمایش کنید اما دستگاه را ندارید، می‌توانید از Firebase Test Lab برای دسترسی به دستگاه‌ها در مرکز داده Google استفاده کنید.

منابع بیشتر