وقتی SDK 35 یا بالاتر را روی دستگاهی با اندروید ۱۵ یا بالاتر هدف قرار دهید، برنامه شما به صورت لبه به لبه نمایش داده میشود. پنجره با کشیدن خطوط پشت میلههای سیستم، کل عرض و ارتفاع صفحه نمایش را در بر میگیرد. میلههای سیستم شامل نوار وضعیت، نوار عنوان و نوار ناوبری هستند.
بسیاری از برنامهها یک نوار برنامه در بالای صفحه دارند. نوار برنامه در بالای صفحه باید تا لبه بالای صفحه کشیده شود و در پشت نوار وضعیت نمایش داده شود. به صورت اختیاری، نوار برنامه در بالای صفحه میتواند هنگام پیمایش محتوا، به ارتفاع نوار وضعیت کوچک شود.
بسیاری از برنامهها همچنین دارای نوار برنامه پایین یا نوار ناوبری پایین هستند. این نوارها همچنین باید تا لبه پایین صفحه نمایش کشیده شوند و در پشت نوار ناوبری نمایش داده شوند. در غیر این صورت، برنامهها باید محتوای پیمایشی را در پشت نوار ناوبری نشان دهند.
هنگام پیادهسازی طرحبندی لبه به لبه در برنامه خود، موارد زیر را در نظر داشته باشید:
- فعال کردن نمایشگر لبه به لبه
- پیادهسازی طرحبندیهای تطبیقی برای بهینهسازی تجربه کاربری در فرمفکتورهای مختلف
- هرگونه همپوشانی بصری را مدیریت کنید
- نمایش اسکریمها را پشت میلههای سیستم در نظر بگیرید

فعال کردن نمایشگر لبه به لبه
اگر برنامه شما SDK 35 یا بالاتر را هدف قرار داده باشد، edge-to-edge به طور خودکار برای دستگاههای اندروید ۱۵ یا بالاتر فعال میشود.
 برای فعال کردن لبه به لبه در نسخههای قبلی اندروید، به صورت دستی enableEdgeToEdge در onCreate از Activity خود فراخوانی کنید. 
کاتلین
 override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         WindowCompat.enableEdgeToEdge(window)
        ...
      }
جاوا
 @Override
      protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WindowCompat.enableEdgeToEdge(getWindow());
        ...
      }
 به طور پیشفرض، enableEdgeToEdge() نوارهای سیستم را شفاف میکند، به جز در حالت ناوبری سه دکمهای که نوار وضعیت یک نوار شفاف میگیرد. رنگ آیکونهای سیستم و نوار شفاف بر اساس تم روشن یا تیره سیستم تنظیم میشود.
 برای فعال کردن نمایش لبه به لبه در برنامه خود بدون استفاده از تابع enableEdgeToEdge() ، به بخش تنظیم دستی نمایش لبه به لبه مراجعه کنید.
همپوشانیها را با استفاده از درجها مدیریت کنید
همانطور که در شکل 3 نشان داده شده است، ممکن است برخی از نماهای برنامه شما پشت نوارهای سیستم ترسیم شوند.
شما میتوانید با واکنش به insetها، همپوشانیها را برطرف کنید، insetها مشخص میکنند که کدام قسمتهای صفحه با رابط کاربری سیستم مانند نوار ناوبری یا نوار وضعیت تلاقی دارند. intersecting میتواند به معنای نمایش بالای محتوا باشد، اما همچنین میتواند برنامه شما را در مورد حرکات سیستم مطلع کند.
انواع درجهایی که برای نمایش لبه به لبه برنامه شما اعمال میشوند عبارتند از:
- درج نوارهای سیستم: بهترین حالت برای نماهایی است که قابل لمس هستند و نباید از نظر بصری توسط نوارهای سیستم مبهم شوند. 
- فرورفتگیهای برش نمایشگر: برای قسمتهایی که ممکن است به دلیل شکل دستگاه، بریدگی صفحه نمایش وجود داشته باشد. 
- درجهای اشاره سیستم: برای نواحی ناوبری اشارهای که توسط سیستم استفاده میشوند و نسبت به برنامه شما اولویت دارند. 
میلههای سیستمی
درجهای نوار سیستم رایجترین نوع درجها هستند. آنها نشاندهندهی ناحیهای هستند که رابط کاربری سیستم در محور Z بالای برنامهی شما نمایش داده میشود. آنها بهترین استفاده را برای جابجایی یا پدگذاری نماها در برنامهی شما دارند که قابل لمس هستند و نباید از نظر بصری توسط نوارهای سیستم مبهم شوند.
برای مثال، دکمه عملیاتی شناور (FAB) در شکل 3 تا حدی توسط نوار ناوبری پنهان شده است:

 برای جلوگیری از این نوع همپوشانی بصری در حالت ژست یا حالت دکمه، میتوانید حاشیههای نما را با استفاده getInsets(int) به همراه WindowInsetsCompat.Type.systemBars() افزایش دهید.
مثال کد زیر نحوه پیادهسازی درج نوار سیستمی را نشان میدهد:
کاتلین
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams> { leftMargin = insets.left bottomMargin = insets.bottom rightMargin = insets.right } // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
جاوا
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
اگر این راهحل را روی مثال نشان داده شده در شکل ۳ اعمال کنید، همانطور که در شکل ۴ نشان داده شده است، هیچ همپوشانی بصری در حالت دکمه مشاهده نمیشود:

همین امر در مورد حالت ناوبری اشارهای نیز صدق میکند، همانطور که در شکل 5 نشان داده شده است:

برشهای نمایشی
بعضی از دستگاهها دارای بریدگی نمایشگر هستند. معمولاً این بریدگی در بالای صفحه نمایش و در نوار وضعیت قرار دارد. وقتی صفحه نمایش دستگاه در حالت افقی است، بریدگی ممکن است در لبه عمودی باشد. بسته به محتوایی که برنامه شما روی صفحه نمایش نشان میدهد، باید برای جلوگیری از بریدگی نمایشگر، فاصلهگذاری (padding) را پیادهسازی کنید، زیرا به طور پیشفرض، برنامهها در بریدگی نمایشگر ترسیم میشوند.
برای مثال، بسیاری از صفحات برنامهها فهرستی از موارد را نشان میدهند. موارد فهرست را با بریدگی نمایشگر یا نوارهای سیستمی مبهم نکنید.
کاتلین
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
جاوا
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { Insets bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
 مقدار WindowInsetsCompat را با گرفتن مقدار منطقی یا از میلههای سیستم و انواع برش صفحه نمایش تعیین کنید.
 clipToPadding روی RecyclerView تنظیم کنید تا padding همراه با آیتمهای لیست اسکرول شود. این کار به آیتمها اجازه میدهد تا هنگام اسکرول کاربر، همانطور که در مثال زیر نشان داده شده است، به پشت میلههای سیستم بروند.
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
درج حرکات سیستم
درجهای حرکات سیستم، نواحی از پنجره را نشان میدهند که در آنها حرکات سیستم نسبت به برنامه شما اولویت دارند. این نواحی در شکل 6 با رنگ نارنجی نشان داده شدهاند:

 مانند درجهای نوار سیستم، میتوانید با استفاده از getInsets(int) به همراه WindowInsetsCompat.Type.systemGestures() از همپوشانی درجهای ژست سیستم جلوگیری کنید.
 از این insetها برای جابجایی یا فاصله دادن نماهای قابل کشیدن از لبهها استفاده کنید. موارد استفاده رایج شامل صفحات پایینی ، کشیدن در بازیها و carouselهایی است که با استفاده از ViewPager2 پیادهسازی شدهاند.
در اندروید ۱۰ یا بالاتر، درج حرکات سیستمی شامل یک درج پایین برای حرکت خانه و یک درج چپ و راست برای حرکات برگشت است:

مثال کد زیر نحوه پیادهسازی درجهای ژست سیستمی را نشان میدهد:
کاتلین
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
جاوا
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
اجزای مواد
 بسیاری از کامپوننتهای متریال اندروید مبتنی بر نماها (com.google.android.material) به طور خودکار insetها را مدیریت میکنند، از جمله BottomAppBar ، BottomNavigationView ، NavigationRailView و NavigationView
 با این حال، AppBarLayout به طور خودکار insetها را مدیریت نمیکند. برای مدیریت insetهای بالا android:fitsSystemWindows="true" را اضافه کنید.
نحوه مدیریت درجها با کامپوننتهای متریال در Compose را بخوانید.
دیسپاچینگ داخلی سازگار با نسخههای قبلی
 برای جلوگیری از ارسال insetها به viewهای فرزند و جلوگیری از over-padding، میتوانید insetها را با استفاده از ثابت WindowInsetsCompat.CONSUMED مصرف کنید. با این حال، در دستگاههایی که اندروید ۱۰ (سطح API ۲۹ و قبل از آن) را اجرا میکنند، insetها پس از فراخوانی WindowInsetsCompat.CONSUMED به siblingها ارسال نمیشوند، که میتواند باعث همپوشانی بصری ناخواسته شود. 

 برای تأیید اینکه insetها برای همه نسخههای اندروید پشتیبانیشده به siblingها ارسال میشوند، قبل از مصرف insetها از ViewGroupCompat#installCompatInsetsDispatch استفاده کنید، که در AndroidX Core و Core-ktx 1.16.0-alpha01 و بالاتر موجود است. 
کاتلین
// Use the i.d. assigned to your layout's root view, e.g. R.id.main val rootView = findViewById(R.id.main) // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView) 
جاوا
// Use the i.d. assigned to your layout's root view, e.g. R.id.main LinearLayout rootView = findViewById(R.id.main); // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView);

حالت فراگیر
 برخی از محتواها در حالت تمام صفحه بهتر دیده میشوند و به کاربر تجربهای فراگیرتر میدهند. میتوانید با استفاده از کتابخانههای WindowInsetsController و WindowInsetsControllerCompat نوارهای سیستم را برای حالت فراگیر پنهان کنید: 
کاتلین
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
جاوا
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
برای اطلاعات بیشتر در مورد پیادهسازی این ویژگی، به بخش «پنهان کردن نوارهای سیستم برای حالت فراگیر» مراجعه کنید.
آیکونهای نوار سیستم
 فراخوانی enableEdgeToEdge تضمین میکند که رنگ آیکونهای نوار سیستم با تغییر تم دستگاه بهروزرسانی شوند.
هنگام استفاده از لبه به لبه، ممکن است لازم باشد رنگ آیکونهای نوار سیستم را به صورت دستی بهروزرسانی کنید تا با پسزمینه برنامه شما در تضاد باشند. به عنوان مثال، برای ایجاد آیکونهای نوار وضعیت روشن:
کاتلین
WindowCompat.getInsetsController(window, window.decorView) .isAppearanceLightStatusBars = false
جاوا
WindowCompat.getInsetsController(window, window.getDecorView()) .setAppearanceLightStatusBars(false);
محافظت از میله سیستم
 زمانی که برنامه شما SDK 35 یا بالاتر را هدف قرار دهد، لبه به لبه اعمال میشود . نوار وضعیت سیستم و نوارهای ناوبری حرکتی شفاف هستند، اما نوار ناوبری سه دکمهای نیمهشفاف است. برای سازگاری با نسخههای قبلی enableEdgeToEdge فراخوانی کنید.
با این حال، ممکن است پیشفرضهای سیستم برای همه موارد استفاده کار نکنند. برای تعیین اینکه آیا از نوارهای سیستمی شفاف یا نیمهشفاف استفاده کنید ، به راهنمای طراحی نوارهای سیستمی اندروید و طراحی لبه به لبه مراجعه کنید.
ایجاد نوارهای سیستم شفاف
 با هدف قرار دادن اندروید ۱۵ (SDK 35) یا بالاتر یا با فراخوانی تابع enableEdgeToEdge() با آرگومانهای پیشفرض برای نسخههای قبلی، یک نوار وضعیت شفاف ایجاد کنید.
 با هدف قرار دادن اندروید ۱۵ یا بالاتر یا با فراخوانی enableEdgeToEdge() با آرگومانهای پیشفرض برای نسخههای قبلی، یک نوار ناوبری ژست شفاف ایجاد کنید. برای نوار ناوبری سه دکمهای، Window.setNavigationBarContrastEnforced را روی false تنظیم کنید، در غیر این صورت یک پارچه شفاف اعمال خواهد شد.
ایجاد میلههای سیستم شفاف
برای ایجاد یک نوار وضعیت شفاف، مراحل زیر را انجام دهید:
-  وابستگی androidx-coreخود را به نسخه ۱.۱۶.۰-beta01 یا بالاتر بهروزرسانی کنید.
-  طرحبندی XML خود را در androidx.core.view.insets.ProtectionLayoutقرار دهید و یک شناسه (ID) به آن اختصاص دهید.
-  به صورت برنامهنویسی شده به ProtectionLayoutدسترسی پیدا کنید تا محافظتها را تنظیم کنید، سمت و یکGradientProtectionبرای نوار وضعیت مشخص کنید.
<androidx.core.view.insets.ProtectionLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list_protection" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:id="@+id/item_list" android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="match_parent"> <!--items--> </ScrollView> </androidx.core.view.insets.ProtectionLayout>
findViewById<ProtectionLayout>(R.id.list_protection) .setProtections( listOf( GradientProtection( WindowInsetsCompat.Side.TOP, // Ideally, this is the pane's background color paneBackgroundColor ) ) )
 مطمئن شوید که ColorInt ارسالی به GradientProtection با پسزمینه محتوا مطابقت دارد. برای مثال، یک طرحبندی list-detail که روی یک صفحه تاشو نمایش داده میشود، ممکن است GradientProtections مختلف با رنگهای مختلف برای پنل لیست و پنل جزئیات داشته باشد. 
نوار ناوبری حرکتی شفاف ایجاد نکنید. برای ایجاد یک نوار ناوبری سه دکمهای شفاف، یکی از موارد زیر را انجام دهید:
-  اگر از قبل طرحبندی خود را در یک ProtectionViewقرار دادهاید، میتوانید یکColorProtectionیاGradientProtectionاضافی را به متدsetProtectionsارسال کنید. قبل از انجام این کار، مطمئن شوید کهwindow.isNavigationBarContrastEnforced = false.
-  در غیر این صورت، window.isNavigationBarContrastEnforced = trueقرار دهید. اگر برنامه شماenableEdgeToEdge, window.isNavigationBarContrastEnforced = trueاست.
نکات دیگر
نکات اضافی هنگام کار با قطعات توکار.
محتوای پیمایشی را لبه به لبه کنید
 با مدیریت درجها و تنظیم clipToPadding روی false ، بررسی کنید که آخرین آیتم لیست توسط نوارهای سیستم در RecyclerView یا NestedScrollView شما پنهان نشده باشد.
 ویدیوی زیر یک RecyclerView با نمایش لبه به لبه غیرفعال (چپ) و فعال (راست) نشان میدهد: 
برای نمونه کد، به قطعه کدهای موجود در بخش «ایجاد لیستهای پویا با RecyclerView» مراجعه کنید.
پنجرههای محاورهای تمامصفحه را لبهبهلبه کنید
 برای اینکه پنجرهی محاورهای تمامصفحه، لبه به لبه باشد، تابع enableEdgeToEdge در پنجرهی محاورهای فراخوانی کنید. 
کاتلین
class MyAlertDialogFragment : DialogFragment() {
    override fun onStart(){
        super.onStart()
        dialog?.window?.let { WindowCompat.enableEdgeToEdge(it) }
    }
    ...
}
جاوا
public class MyAlertDialogFragment extends DialogFragment {
    @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();
        if (dialog != null) {
            Window window = dialog.getWindow();
            if (window != null) {
                WindowCompat.enableEdgeToEdge(window);
            }
        }
    }
    ...
}
منابع اضافی
برای اطلاعات بیشتر در مورد لبه به لبه به منابع زیر مراجعه کنید.
وبلاگها
- نکاتی برای مدیریت Insetها در اندروید ۱۵ با پشتیبانی کامل از همه جهات
- WindowInsets — شنوندههای طرحبندیها
طراحی
سایر مستندات
ویدیوها
 
  