WindowInsets میانای برنامهسازی کاربردی استاندارد در Jetpack Compose برای مدیریت
نواحی صفحهنمایش است که بهطور جزئی یا کامل توسط میانای کاربری سیستم پوشیده شدهاند. این
نواحی شامل نوار وضعیت، نوار پیمایش، و صفحهکلید مجازی میشود. میتوانید بهجای آن، WindowInsetsRulers ازپیش تعریفشدهای مثل
SafeDrawing را به Modifier.fitInside یا Modifier.fitOutside
منتقل کنید تا محتوایتان را با نوارهای سیستم و برش نمایشگر تراز کنید یا WindowInsetsRulers سفارشی ایجاد کنید.
مزایای WindowInsetsRulers
- از پیچیدگی مصرف اجتناب میکند: درطول مرحله جایگذاری چیدمان عمل میکند. این یعنی کاملاً از زنجیره مصرف درج عبور میکند و
همیشه میتواند موقعیتهای مطلق و صحیح نوارهای سیستم و
برشهای نمایشگر را بدون توجه به آنچه چیدمانهای والد انجام دادهاند ارائه دهد. استفاده از روشهای
Modifier.fitInsideیاModifier.fitOutsideدر رفع مشکلات زمانی که «عناصر ترکیبشدنی» اجدادی بهطور نادرست حاشیهها را مصرف میکنند مفید است. - بهراحتی از نوارهای سیستم اجتناب کنید: این ویژگی به محتوای برنامه شما کمک میکند از نوارهای سیستم
و برش نمایشگر اجتناب کند و میتواند سادهتر از استفاده مستقیم از
WindowInsetsباشد. - بسیار قابلسفارشیسازی: توسعهدهندگان میتوانند محتوا را با خطکشهای سفارشی تراز کنند و با چیدمانهای سفارشی، کنترل دقیقی بر چیدمانهای خود داشته باشند.
معایب WindowInsetsRulers
- نمیتواند برای «اندازهگیری» استفاده شود: چون در مرحله جای آگهی عمل میکند، اطلاعات مکانی که ارائه میدهد در مرحله اندازهگیری قبلی دردسترس نیست.
محتوایتان را با روشهای «اصلاحگر» هماهنگ کنید
Modifier.fitInside به برنامهها اجازه میدهد محتوا را با نوارهای سیستم و
برشهای نمایشگر تراز کنند. میتواند بهجای WindowInsets استفاده شود.
Modifier.fitOutside معمولاً معکوس Modifier.fitInside است.
برای مثال، برای تأیید اینکه محتوای برنامه از نوارهای سیستم و
برش نمایشگر استفاده نمیکند، میتوانید از fitInside(WindowInsetsRulers.safeDrawing.current) استفاده کنید.
@Composable fun FitInsideDemo(modifier: Modifier) { Box( modifier = modifier .fillMaxSize() // Or DisplayCutout, Ime, NavigationBars, StatusBar, etc... .fitInside(WindowInsetsRulers.SafeDrawing.current) ) }
جدول زیر نشان میدهد محتوای برنامه شما با خطکشهای ازپیشتعریفشده با Modifier.fitInside یا Modifier.fitOutside چگونه خواهد بود.
| نوع خطکش ازپیش تعریفشده | ||
|---|---|---|
![]() |
![]() |
|
![]() |
موجود نیست |
|
![]() |
![]() |
|
![]() |
موجود نیست (بهجای آن از |
|
![]() |
![]() |
استفاده از Modifier.fitInside و Modifier.fitOutside مستلزم محدود شدن عناصر ترکیبپذیر است. این یعنی باید اصلاحگرهایی مثل
Modifier.size یا Modifier.fillMaxSize را تعریف کنید.
برخیاز خطکشها مثل Modifier.fitOutside در SafeDrawing و SystemBars چندین خطکش برمیگردانند. در این حالت، Android عنصر Composable را بااستفاده از یک خطکش
از چپ، بالا، راست، پایین قرار میدهد.
با Modifier.fitInside از IME اجتناب کنید
برای مدیریت عناصر پایین با «ویرایشگر روش ورودی» با Modifier.fitInside،
RectRuler را که درونیترین مقدار NavigationBar و Ime را میگیرد اضافه کنید.
@Composable fun FitInsideWithImeDemo(modifier: Modifier) { Box( modifier = modifier .fillMaxSize() .fitInside( RectRulers.innermostOf( WindowInsetsRulers.NavigationBars.current, WindowInsetsRulers.Ime.current ) ) ) { TextField( value = "Demo IME Insets", onValueChange = {}, modifier = modifier.align(Alignment.BottomStart).fillMaxWidth() ) } }
با «اصلاحگر.درونبرازنده» از نوار وضعیت و نوار زیرنویس ناشنوایان اجتناب کنید
بههمین ترتیب، برای درستیسنجی عناصر بالا، از نوار وضعیت و نوار زیرنویس ناشنوایان با Modifier.fitInside اجتناب کنید، RectRuler را بگذرانید که درونیترین مقدار StatusBars و CaptionBar را میگیرد.
@Composable fun FitInsideWithStatusAndCaptionBarDemo(modifier: Modifier) { Box( modifier = modifier .fillMaxSize() .fitInside( RectRulers.innermostOf( WindowInsetsRulers.StatusBars.current, WindowInsetsRulers.CaptionBar.current ) ) ) }
ساختن WindowInsetsRulers سفارشی
میتوانید محتوا را با خطکشهای سفارشی تراز کنید. برای مثال، مورد استفادهای را درنظر بگیرید که در آن
ترکیبشدنی والد بهدرستی از حاشیهها استفاده نمیکند و باعث ایجاد مشکلات حاشیهگذاری در
فرزند پاییندست میشود. اگرچه این مشکل را میتوان به روشهای دیگری نیز حل کرد، ازجمله بااستفاده از Modifier.fitInside، اما میتوانید خطکش سفارشی هم بسازید تا عنصر ترکیبی کودک را دقیقاً تراز کنید بدون اینکه لازم باشد مشکل را در بالادست والد برطرف کنید، همانطور که در مثال و ویدیو زیر نشان داده شده است:
@Composable fun WindowInsetsRulersDemo(modifier: Modifier) { Box( contentAlignment = BottomCenter, modifier = modifier .fillMaxSize() // The mistake that causes issues downstream, as .padding doesn't consume insets. // While it's correct to instead use .windowInsetsPadding(WindowInsets.navigationBars), // assume it's difficult to identify this issue to see how WindowInsetsRulers can help. .padding(WindowInsets.navigationBars.asPaddingValues()) ) { TextField( value = "Demo IME Insets", onValueChange = {}, modifier = modifier // Use alignToSafeDrawing() instead of .imePadding() to precisely place this child // Composable without having to fix the parent upstream. .alignToSafeDrawing() // .imePadding() // .fillMaxWidth() ) } } fun Modifier.alignToSafeDrawing(): Modifier { return layout { measurable, constraints -> if (constraints.hasBoundedWidth && constraints.hasBoundedHeight) { val placeable = measurable.measure(constraints) val width = placeable.width val height = placeable.height layout(width, height) { val bottom = WindowInsetsRulers.SafeDrawing.current.bottom .current(0f).roundToInt() - height val right = WindowInsetsRulers.SafeDrawing.current.right .current(0f).roundToInt() val left = WindowInsetsRulers.SafeDrawing.current.left .current(0f).roundToInt() measurable.measure(Constraints.fixed(right - left, height)) .place(left, bottom) } } else { val placeable = measurable.measure(constraints) layout(placeable.width, placeable.height) { placeable.place(0, 0) } } } }
ویدیو زیر نمونهای از مصرف درج IME مشکلساز را نشان میدهد
که بهدلیل والد بالادستی در تصویر سمت راست ایجاد شده است، و از خطکشهای سفارشی
برای رفع مشکل در سمت چپ استفاده میکند. فاصله اضافی در زیر TextField
Composable نشان داده میشود زیرا فاصله نوار پیمایش توسط عنصر والد مصرف نشده است. کودک بااستفاده از خطکش سفارشی در مکان صحیح در تصویر سمت راست قرار میگیرد،
همانطور که در نمونه کد قبلی دیده میشود.
تأیید کنید که والدین محدود شدهاند
برای استفاده ایمن از WindowInsetsRulers، مطمئن شوید ولی محدودیتهای معتبری ارائه دهد. والدین باید اندازه مشخصی داشته باشند و نمیتوانند به اندازه فرزندی که از WindowInsetsRulers استفاده میکند وابسته باشند. از fillMaxSize یا اصلاحکنندههای اندازه دیگر
در «ترکیبپذیرهای» والد استفاده کنید.
بههمین ترتیب، قرار دادن عنصر ترکیبی که از WindowInsetsRulers در
ظرف پیمایشی مثل verticalScroll استفاده میکند میتواند باعث عملکرد غیرمنتظره شود زیرا
ظرف پیمایشی محدودیتهای ارتفاع نامحدود ارائه میدهد که با منطق خطکش ناسازگار است.







