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

روش نوشتن را امتحان کنید
Jetpack Compose ابزار رابط کاربری پیشنهادی برای اندروید است. یاد بگیرید که چگونه با طرح‌بندی‌های واکنش‌گرا در Compose کار کنید.

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

طراحی واکنش‌گرا

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

طرح محدودیت

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

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

شکل ۳. ویرایشگر طرح‌بندی در اندروید استودیو که 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 ) باشد، که این امر باعث می‌شود view بتواند با ابعاد مختلف نمایش و مقادیر مختلف متن سازگار شود.

اگر از 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 را تعیین می‌کنند. در مثال، اگر پنجره به اندازه کافی بزرگ باشد (حداقل 580dp عرض) تا هر دو نما را نمایش دهد، پنجره‌ها در کنار هم نمایش داده می‌شوند. اما اگر عرض پنجره کمتر از 580dp باشد، پنجره‌ها روی یکدیگر می‌لغزند تا به صورت جداگانه کل پنجره برنامه را اشغال کنند.

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

منابع طرح‌بندی جایگزین

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

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

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

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

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

توصیفگر کوچکترین عرض

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

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

برای مثال، می‌توانید با ایجاد نسخه‌های مختلف فایل در دایرکتوری‌های مختلف، یک طرح‌بندی با نام 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)
  • 720dp: تبلت 10 اینچی (720x1280 mdpi، 800x1280 mdpi، و غیره)

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

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

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

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

توصیفگر عرض موجود

به جای تغییر طرح‌بندی بر اساس کوچکترین عرض نمایشگر، می‌توانید طرح‌بندی خود را بر اساس میزان عرض یا ارتفاع موجود تغییر دهید. برای مثال، ممکن است بخواهید هر زمان که صفحه نمایش حداقل ۶۰۰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 برای صفحاتی با حداقل ارتفاع 600dp.

معیارهای جهت‌یابی

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

برای این کار، می‌توانید توصیف‌کننده‌های port یا land را به نام‌های دایرکتوری layout خود اضافه کنید. فقط مطمئن شوید که توصیف‌کننده‌های orientation بعد از توصیف‌کننده‌های size می‌آیند. برای مثال:

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 در بالا مراجعه کنید) می‌تواند با یک قطعه حاوی لیست و قطعه دیگری حاوی جزئیات آیتم‌های لیست پیاده‌سازی شود. در صفحه نمایش‌های بزرگ، قطعات می‌توانند در کنار هم نمایش داده شوند؛ در صفحه نمایش‌های کوچک، به صورت جداگانه، و کل صفحه را پر کنند.

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

تعبیه فعالیت

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

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

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

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

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

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

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

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

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

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

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

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

منابع اضافی