WindowInsets
API استاندارد در Jetpack Compose برای مدیریت مناطقی از صفحه است که به طور جزئی یا کامل توسط رابط کاربری سیستم مبهم هستند. این مناطق شامل نوار وضعیت، نوار ناوبری و صفحه کلید روی صفحه است. همچنین میتوانید WindowInsetsRulers
از پیش تعریفشده مانند SafeDrawing
را به Modifier.fitInside
یا Modifier.fitOutside
بفرستید تا محتوای خود را با نوارهای سیستم و بریدگی نمایش همتراز کنید یا WindowInsetsRulers
سفارشی ایجاد کنید.
مزایای WindowInsetsRulers
- از پیچیدگی مصرف جلوگیری می کند : در مرحله قرار دادن چیدمان عمل می کند. این بدان معناست که به طور کامل زنجیره مصرف داخلی را دور میزند و همیشه میتواند موقعیتهای صحیح و مطلق نوارهای سیستم و برشهای نمایشگر را بدون توجه به اینکه چیدمانهای والد انجام دادهاند، ارائه دهد. استفاده از روشهای
Modifier.fitInside
یاModifier.fitOutside
برای رفع مشکلات زمانی که Composables اجدادی بهدرستی از اینستها استفاده میکنند، مفید است. - به راحتی از نوارهای سیستم اجتناب کنید : به محتوای برنامه شما کمک می کند از نوارهای سیستم و بریدگی نمایشگر جلوگیری کند و می تواند ساده تر از استفاده مستقیم از
WindowInsets
باشد. - بسیار قابل تنظیم : توسعه دهندگان می توانند محتوا را با خط کش های سفارشی تراز کنند و با طرح بندی های سفارشی کنترل دقیقی بر روی طرح بندی های خود داشته باشند.
معایب WindowInsetsRulers
- نمی توان برای اندازه گیری استفاده کرد : از آنجایی که در مرحله قرار دادن عمل می کند، اطلاعات موقعیتی که ارائه می دهد در مرحله اندازه گیری قبلی در دسترس نیست .
محتوای خود را با متدهای Modifier تراز کنید
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
چگونه خواهد بود.
نوع خط کش از پیش تعریف شده | ||
---|---|---|
![]() | ![]() | |
![]() | N/A | |
![]() | ![]() | |
![]() | N/A (به جای آن از | |
![]() | ![]() |
استفاده از Modifier.fitInside
و Modifier.fitOutside
مستلزم این است که composable ها محدود باشند. این بدان معنی است که شما باید اصلاح کننده هایی مانند Modifier.size
یا Modifier.fillMaxSize
را تعریف کنید.
برخی از خط کش ها مانند Modifier.fitOutside
در SafeDrawing
و SystemBars
چندین خط کش را برمی گردانند. در این حالت، اندروید Composable را با استفاده از یک خط کش از سمت چپ، بالا، راست، پایین قرار می دهد.
از IME با 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 اجتناب کنید
به طور مشابه، برای تأیید عناصر بالا از نوار وضعیت و نوار شرح همراه با Modifier.fitInsider
اجتناب کنید، یک 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 inset ناشی از والد بالادستی را در تصویر سمت چپ نشان می دهد و از خط کش های سفارشی برای رفع مشکل در سمت راست استفاده می کند. بالشتک اضافی در زیر TextField
Composable نشان داده شده است زیرا نوار ناوبری توسط والدین مصرف نشده است. همانطور که در نمونه کد قبلی مشاهده می شود، کودک با استفاده از یک خط کش سفارشی در مکان صحیح در تصویر سمت راست قرار می گیرد.
بررسی کنید که والدین محدود هستند
برای استفاده ایمن از WindowInsetsRulers
، مطمئن شوید که والد محدودیتهای معتبری را ارائه میکند. والدین باید اندازه مشخصی داشته باشند و نمیتوانند به اندازه فرزندی که از WindowInsetsRulers
استفاده میکند وابسته باشند. از fillMaxSize
یا سایر اصلاح کننده های اندازه در Composables والد استفاده کنید.
به طور مشابه، قرار دادن یک composable که از WindowInsetsRulers
در داخل یک محفظه پیمایشی مانند verticalScroll
استفاده میکند، میتواند رفتار غیرمنتظرهای ایجاد کند، زیرا ظرف پیمایش محدودیتهای ارتفاع نامحدودی را ارائه میکند که با منطق خطکش ناسازگار است.