اطمینان حاصل کنید که رابط کاربری شما با ورودی های پنجره کار می کند

هنگامی که Activity شما کنترل همه موارد داخلی را به دست گرفت، می توانید از Compose API استفاده کنید تا مطمئن شوید که محتوا مبهم نیست و عناصر قابل تعامل با رابط کاربری سیستم همپوشانی ندارند. این APIها همچنین چیدمان برنامه شما را با تغییرات داخلی همگام می کنند.

به عنوان مثال، این ابتدایی ترین روش اعمال inset ها در محتوای کل برنامه شما است:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    enableEdgeToEdge()

    setContent {
        Box(Modifier.safeDrawingPadding()) {
            // the rest of the app
        }
    }
}

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

همه این انواع inset به طور خودکار با انیمیشن‌های IME که به API 21 پس‌پورت شده‌اند، متحرک می‌شوند. با گسترش، همه طرح‌بندی‌های شما با استفاده از این inset‌ها نیز به‌طور خودکار با تغییر مقادیر inset متحرک می‌شوند.

دو روش اصلی برای استفاده از این انواع داخلی برای تنظیم طرح‌بندی‌های Composable وجود دارد: اصلاح‌کننده‌های padding و اصلاح‌کننده اندازه inset.

اصلاح کننده های پد

Modifier.windowInsetsPadding(windowInsets: WindowInsets) ورودی های پنجره داده شده را به عنوان padding اعمال می کند، درست مانند Modifier.padding . به عنوان مثال، Modifier.windowInsetsPadding(WindowInsets.safeDrawing) ورودی های طراحی ایمن را به عنوان بالشتک در هر 4 طرف اعمال می کند.

همچنین چندین روش کاربردی داخلی برای رایج ترین انواع داخلی وجود دارد. Modifier.safeDrawingPadding() یکی از این روشها است که معادل Modifier.windowInsetsPadding(WindowInsets.safeDrawing) است. اصلاح کننده های مشابهی برای سایر انواع داخلی وجود دارد.

اصلاح‌کننده‌های اندازه داخلی

اصلاح‌کننده‌های زیر با تنظیم اندازه مؤلفه به اندازه ورودی‌ها، مقداری از ورودی‌های پنجره را اعمال می‌کنند:

Modifier.windowInsetsStartWidth(windowInsets: WindowInsets)

سمت شروع windowInsets را به عنوان عرض اعمال می کند (مانند Modifier.width )

Modifier.windowInsetsEndWidth(windowInsets: WindowInsets)

سمت انتهایی windowInsets را به عنوان عرض اعمال می کند (مانند Modifier.width )

Modifier.windowInsetsTopHeight(windowInsets: WindowInsets)

سمت بالای windowInsets را به عنوان ارتفاع اعمال می کند (مانند Modifier.height )

Modifier.windowInsetsBottomHeight(windowInsets: WindowInsets)

سمت پایین windowInsets را به عنوان ارتفاع اعمال می کند (مانند Modifier.height )

این اصلاح‌کننده‌ها به‌ویژه برای اندازه‌گیری یک Spacer که فضای ورودی‌ها را اشغال می‌کند مفید هستند:

LazyColumn(
    Modifier.imePadding()
) {
    // Other content
    item {
        Spacer(
            Modifier.windowInsetsBottomHeight(
                WindowInsets.systemBars
            )
        )
    }
}

مصرف داخلی

اصلاح‌کننده‌های padding ( windowInsetsPadding و کمک‌هایی مانند safeDrawingPadding ) به‌طور خودکار بخشی از inset‌هایی را که به‌عنوان padding اعمال می‌شوند مصرف می‌کنند. در حالی که عمیق‌تر به درخت ترکیب می‌روید، اصلاح‌کننده‌های بالشتک درونی تودرتو و اصلاح‌کننده‌های اندازه درونی می‌دانند که برخی از قسمت‌های داخلی قبلاً توسط اصلاح‌کننده‌های لایه داخلی مصرف شده‌اند، و از استفاده بیش از یک‌بار از همان بخش داخلی‌ها که منجر به فضای بیش‌ازحد می‌شود، اجتناب کنید.

اصلاح‌کننده‌های اندازه داخلی همچنین از استفاده بیش از یک‌بار از همان قسمت داخلی خودداری می‌کنند، در صورتی که اینست‌ها قبلاً مصرف شده باشند. با این حال، از آنجایی که آنها به طور مستقیم اندازه خود را تغییر می دهند، خودشان دمنوش ها را مصرف نمی کنند.

در نتیجه، اصلاح‌کننده‌های بالشتک تودرتو به‌طور خودکار میزان padding اعمال‌شده برای هر ترکیب‌سازی را تغییر می‌دهند.

با نگاهی به مثال LazyColumn قبلی، اندازه LazyColumn توسط اصلاح کننده imePadding تغییر می کند. در داخل LazyColumn ، آخرین مورد به اندازه ارتفاع پایین نوارهای سیستم است:

LazyColumn(
    Modifier.imePadding()
) {
    // Other content
    item {
        Spacer(
            Modifier.windowInsetsBottomHeight(
                WindowInsets.systemBars
            )
        )
    }
}

هنگامی که IME بسته است، اصلاح کننده imePadding() هیچ padding اعمال نمی کند، زیرا IME ارتفاع ندارد. از آنجایی که اصلاح‌کننده imePadding() هیچ بالشتکی اعمال نمی‌کند، هیچ ورودی مصرف نمی‌شود و ارتفاع Spacer به اندازه سمت پایین میله‌های سیستم خواهد بود.

هنگامی که IME باز می شود، IME برای مطابقت با اندازه IME، متحرک سازی را وارد می کند، و اصلاح کننده imePadding() شروع به اعمال padding پایین برای تغییر اندازه LazyColumn با باز شدن IME می کند. هنگامی که اصلاح کننده imePadding() شروع به اعمال لایه پایین می کند، شروع به مصرف آن مقدار inset نیز می کند. بنابراین، ارتفاع Spacer شروع به کاهش می کند، زیرا بخشی از فاصله برای نوارهای سیستم قبلاً توسط اصلاح کننده imePadding() اعمال شده است. هنگامی که اصلاح کننده imePadding() مقداری از لایه پایینی را که بزرگتر از نوارهای سیستم است اعمال می کند، ارتفاع Spacer صفر می شود.

وقتی IME بسته می‌شود، تغییرات به صورت معکوس اتفاق می‌افتد: زمانی که imePadding() کمتر از قسمت پایین نوارهای سیستم اعمال شود، Spacer شروع به گسترش از ارتفاع صفر می‌کند، تا اینکه در نهایت هنگامی که IME کاملاً متحرک شد، Spacer با ارتفاع سمت پایین نوارهای سیستم مطابقت پیدا کرد.

شکل 2. ستون تنبل لبه به لبه با TextField .

این رفتار از طریق ارتباط بین همه اصلاح‌کننده‌های windowInsetsPadding انجام می‌شود و می‌تواند به چند روش دیگر تحت تأثیر قرار گیرد.

Modifier.consumeWindowInsets(insets: WindowInsets) نیز مانند Modifier.windowInsetsPadding ، ورودی‌ها را مصرف می‌کند، اما ورودی‌های مصرف‌شده را به‌عنوان padding اعمال نمی‌کند. این در ترکیب با اصلاح‌کننده‌های اندازه داخلی مفید است، تا به خواهر و برادر نشان دهد که مقدار مشخصی از اینست قبلاً مصرف شده است:

Column(Modifier.verticalScroll(rememberScrollState())) {
    Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars))

    Column(
        Modifier.consumeWindowInsets(
            WindowInsets.systemBars.only(WindowInsetsSides.Vertical)
        )
    ) {
        // content
        Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
    }

    Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars))
}

Modifier.consumeWindowInsets(paddingValues: PaddingValues) بسیار شبیه به نسخه دارای آرگومان WindowInsets عمل می کند، اما برای مصرف یک PaddingValues ​​دلخواه می گیرد. این برای اطلاع دادن به کودکان مفید است زمانی که بالشتک یا فاصله با مکانیسم دیگری غیر از اصلاح‌کننده‌های بالشتک داخلی، مانند یک Modifier.padding معمولی یا فاصله‌دهنده ارتفاع ثابت، ارائه می‌شود:

Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) {
    // content
    Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime))
}

در مواردی که ورودی‌های پنجره خام بدون مصرف مورد نیاز هستند، از مقادیر WindowInsets مستقیماً استفاده کنید یا از WindowInsets.asPaddingValues() برای برگرداندن PaddingValues ​​از ورودی‌هایی که تحت تأثیر مصرف نیستند، استفاده کنید. با این حال، با توجه به هشدارهای زیر، ترجیح می‌دهید تا حد امکان از اصلاح‌کننده‌های padding insets و تعدیل‌کننده‌های اندازه insets پنجره استفاده کنید.

مراحل Insets و Jetpack Compose

Compose از APIهای اصلی AndroidX برای به‌روزرسانی و متحرک سازی inset‌ها استفاده می‌کند، که از APIهای پلتفرم زیربنایی برای مدیریت ورودی‌ها استفاده می‌کنند. به دلیل رفتار پلتفرم، Inset ها رابطه خاصی با فازهای Jetpack Compose دارند.

ارزش inset ها پس از مرحله ترکیب، اما قبل از مرحله طرح بندی به روز می شوند. این بدان معنی است که خواندن مقدار insets در ترکیب معمولاً از مقدار insets استفاده می کند که یک فریم تاخیر دارد. اصلاح‌کننده‌های داخلی توضیح‌داده‌شده در این صفحه به گونه‌ای ساخته شده‌اند که استفاده از مقادیر ورودی‌ها را تا مرحله طرح‌بندی به تأخیر بیاندازند، که تضمین می‌کند که مقادیر ورودی در همان قاب به‌روزرسانی شده استفاده می‌شوند.