پشتیبانی از برش های نمایشگر

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

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

اندروید از بریدگی نمایشگر در دستگاه‌هایی که اندروید ۹ (سطح API 28) و بالاتر دارند پشتیبانی می‌کند. با این حال، تولیدکنندگان دستگاه می‌توانند از بریدگی نمایشگر در دستگاه‌هایی که اندروید ۸.۱ یا پایین‌تر دارند نیز پشتیبانی کنند.

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

تصویری که نمونه‌ای از بریدگی بالای صفحه نمایش در مرکز را نشان می‌دهد
شکل ۱. ۱ برش نمایشگر.

نحوه برخورد برنامه با نواحی برش خورده را انتخاب کنید

اگر نمی‌خواهید محتوای شما با ناحیه برش همپوشانی داشته باشد، معمولاً کافی است مطمئن شوید که محتوای شما با نوار وضعیت و نوار ناوبری همپوشانی ندارد. اگر در حال رندر کردن در ناحیه برش هستید، از WindowInsetsCompat.getDisplayCutout() برای بازیابی یک شیء DisplayCutout که شامل حاشیه‌های امن و کادر محدودکننده برای هر برش است، استفاده کنید. این APIها به شما امکان می‌دهند بررسی کنید که آیا محتوای شما با برش همپوشانی دارد یا خیر تا در صورت نیاز بتوانید موقعیت آن را تغییر دهید.

همچنین می‌توانید تعیین کنید که آیا محتوا پشت ناحیه برش قرار گیرد یا خیر. ویژگی layout پنجره layoutInDisplayCutoutMode نحوه ترسیم محتوای شما در ناحیه برش را کنترل می‌کند. می‌توانید layoutInDisplayCutoutMode روی یکی از مقادیر زیر تنظیم کنید:

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT : محتوا زمانی در ناحیه برش رندر می‌شود که برش نمایشگر در یک نوار سیستم قرار داشته باشد. در غیر این صورت، پنجره روی برش نمایشگر قرار نمی‌گیرد؛ برای مثال، ممکن است محتوا هنگام نمایش در حالت افقی به صورت جعبه‌ای حروف‌دار نمایش داده شود. اگر برنامه شما SDK 35 را هدف قرار می‌دهد، این برای پنجره‌های غیر شناور به صورت ALWAYS تفسیر می‌شود.
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS : محتوا همیشه مجاز است تا نواحی برش را گسترش دهد. اگر برنامه شما SDK 35 را هدف قرار داده و روی دستگاه اندروید ۱۵ اجرا می‌شود، این تنها حالت مجاز برای پنجره‌های غیر شناور است تا نمایش لبه به لبه تضمین شود.
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES : محتوا در هر دو حالت عمودی و افقی در ناحیه برش رندر می‌شود. برای پنجره‌های شناور استفاده نکنید. اگر برنامه شما SDK 35 را هدف قرار می‌دهد، این برای پنجره‌های غیر شناور به عنوان ALWAYS تفسیر می‌شود.
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER : محتوا هرگز در ناحیه برش رندر نمی‌شود. اگر برنامه شما SDK 35 را هدف قرار می‌دهد، این برای پنجره‌های غیرشناور به عنوان ALWAYS تفسیر می‌شود.

شما می‌توانید حالت برش را یا به صورت برنامه‌نویسی یا با تنظیم یک سبک در activity خود تنظیم کنید. مثال زیر یک سبک برای اعمال ویژگی LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES به activity تعریف می‌کند.

<style name="ActivityTheme">
  <item name="android:windowLayoutInDisplayCutoutMode">
    shortEdges <!-- default, shortEdges, or never -->
  </item>
</style>

بخش‌های بعدی حالت‌های مختلف برش را با جزئیات بیشتری شرح می‌دهند.

رفتار پیش‌فرض

اگر برنامه شما SDK 35 را هدف قرار داده و روی دستگاهی با اندروید ۱۵ اجرا می‌شود، LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS رفتار پیش‌فرض است و LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT برای پنجره‌های غیرشناور به صورت LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS تفسیر می‌شود.

در غیر این صورت، LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT مقدار پیش‌فرض است.

رندر محتوا در نواحی برش با لبه کوتاه

اگر برنامه شما SDK 35 را هدف قرار داده و روی دستگاهی با اندروید ۱۵ اجرا می‌شود، LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES برای پنجره‌های غیرشناور به صورت LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS تفسیر می‌شود.

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

تصویر زیر نمونه‌ای از LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES برای دستگاهی در حالت عمودی است:

تصویری که نشان می‌دهد محتوا در حالت عمودی در ناحیه برش رندر می‌شود
شکل ۲. رندر محتوا در ناحیه برش در حالت عمودی

تصویر زیر نمونه‌ای از LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES برای دستگاهی در حالت افقی است:

تصویری که نشان می‌دهد محتوا در حالت افقی در ناحیه برش رندر می‌شود
شکل ۳. رندر محتوا در ناحیه برش در حالت افقی

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

بریدگی در گوشه، لبه کوتاه محسوب می‌شود:

تصویری که دستگاهی با بریدگی گوشه را نشان می‌دهد
شکل ۴. دستگاهی با بریدگی گوشه.

هرگز محتوا را در ناحیه بریدگی نمایشگر رندر نکنید

اگر برنامه شما SDK 35 را هدف قرار داده و روی دستگاهی با اندروید ۱۵ اجرا می‌شود، LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER برای پنجره‌های غیرشناور به صورت LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS تفسیر می‌شود.

با LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER ، پنجره هرگز اجازه ندارد با ناحیه برش همپوشانی داشته باشد.

مثال زیر از LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER در حالت عمودی است:

تصویری که LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER را برای حالت عمودی نشان می‌دهد
شکل ۵. مثالی از LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER برای حالت عمودی.

مثال زیر مربوط به LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER در حالت افقی است:

تصویری که LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER را برای حالت افقی نشان می‌دهد
شکل ۶. مثالی از LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER در حالت افقی.

بهترین روش‌ها برای پشتیبانی از بریدگی نمایشگر

هنگام کار با برش‌های نمایشگر، موارد زیر را در نظر بگیرید:

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

    تصویری که نشان می‌دهد محتوا به دلیل تنظیم نادرست insetها از بالا بریده شده است
    شکل ۷. WindowInsetsCompat برای جلوگیری از همپوشانی یا قطع محتوا استفاده کنید.
  • از View.getLocationInWindow() برای تعیین میزان فضای اشغال شده توسط برنامه خود استفاده کنید. فرض نکنید که برنامه از کل پنجره استفاده می‌کند و View.getLocationOnScreen() نیز استفاده نکنید.

  • اگر برنامه شما نیاز به انتقال به حالت فراگیر و خروج از آن دارد، از حالت‌های برش always ، shortEdges یا never استفاده کنید. رفتار پیش‌فرض برش می‌تواند باعث شود محتوای برنامه شما در ناحیه برش در حالی که نوارهای سیستم وجود دارند رندر شود، اما در حالت فراگیر این اتفاق نمی‌افتد. این امر منجر به بالا و پایین رفتن محتوا در حین انتقال می‌شود، همانطور که در مثال زیر نشان داده شده است.

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

    تصویری که مختصات پنجره را در مقابل صفحه نمایش، هنگامی که محتوا به صورت حروف بزرگ نمایش داده می‌شود، نشان می‌دهد.
    شکل ۹. مختصات پنجره در مقابل صفحه نمایش هنگامی که محتوا به صورت جعبه‌ای حروفی نمایش داده می‌شود.
  • هنگام مدیریت MotionEvent ، MotionEvent.getX() و MotionEvent.getY() برای جلوگیری از مشکلات مختصات مشابه استفاده کنید. MotionEvent.getRawX() یا MotionEvent.getRawY() استفاده نکنید.

نحوه رندر شدن محتوای خود را آزمایش کنید

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

  1. گزینه‌های توسعه‌دهنده را فعال کنید.
  2. در صفحه گزینه‌های توسعه‌دهندگان ، به پایین اسکرول کنید تا به بخش طراحی (Drawing ) برسید و گزینه شبیه‌سازی نمایشگر با بریدگی (Simulate a display with a cutout) را انتخاب کنید.
  3. نوع برش را انتخاب کنید.

    تصویری که نحوه شبیه‌سازی بریدگی نمایشگر در شبیه‌ساز را نشان می‌دهد
    شکل ۱۰. گزینه‌های توسعه‌دهنده برای آزمایش نحوه‌ی رندر محتوای شما.

منابع اضافی