درباره WindowInsetsRulers

WindowInsets API استاندارد در Jetpack Compose برای مدیریت مناطقی از صفحه است که به طور جزئی یا کامل توسط رابط کاربری سیستم مبهم هستند. این مناطق شامل نوار وضعیت، نوار ناوبری و صفحه کلید روی صفحه است. همچنین می‌توانید WindowInsetsRulers از پیش تعریف‌شده مانند SafeDrawing را به Modifier.fitInside یا Modifier.fitOutside بفرستید تا محتوای خود را با نوارهای سیستم و بریدگی نمایش هم‌تراز کنید یا WindowInsetsRulers سفارشی ایجاد کنید.

مزایای WindowInsetsRulers

  • از پیچیدگی مصرف جلوگیری می کند : در مرحله قرار دادن چیدمان عمل می کند. این بدان معناست که به طور کامل زنجیره مصرف داخلی را دور می‌زند و همیشه می‌تواند موقعیت‌های صحیح و مطلق نوارهای سیستم و برش‌های نمایشگر را بدون توجه به اینکه چیدمان‌های والد انجام داده‌اند، ارائه دهد. استفاده از روش‌های Modifier.fitInside یا Modifier.fitOutside برای رفع مشکلات زمانی که Composables اجدادی به‌درستی از اینست‌ها استفاده می‌کنند، مفید است.
  • به راحتی از نوارهای سیستم اجتناب کنید : به محتوای برنامه شما کمک می کند از نوارهای سیستم و بریدگی نمایشگر جلوگیری کند و می تواند ساده تر از استفاده مستقیم از WindowInsets باشد.
  • بسیار قابل تنظیم : توسعه دهندگان می توانند محتوا را با خط کش های سفارشی تراز کنند و با طرح بندی های سفارشی کنترل دقیقی بر روی طرح بندی های خود داشته باشند.

معایب WindowInsetsRulers

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

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 استفاده می‌کند، می‌تواند رفتار غیرمنتظره‌ای ایجاد کند، زیرا ظرف پیمایش محدودیت‌های ارتفاع نامحدودی را ارائه می‌کند که با منطق خط‌کش ناسازگار است.