راه‌اندازی حاشیه‌های پنجره

پس‌از اینکه «فعالیت» شما کنترل مدیریت همه درج‌ها را دراختیار گرفت، می‌توانید از APIs «نگارش» برای تأیید اینکه محتوا پوشیده نشده است و عناصر تعاملی با واسط کاربر سیستم هم‌پوشانی ندارند استفاده کنید. این «میاناهای برنامه‌سازی کاربردی» همچنین چیدمان برنامه شما را با تغییرات حاشیه همگام‌سازی می‌کنند.

مدیریت حاشیه‌ها بااستفاده از اصلاح‌کننده‌های اندازه یا بالشتک

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

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

    enableEdgeToEdge()

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

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

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

سه روش برای مدیریت حاشیه‌ها برای تنظیم چیدمان‌های «ترکیب‌پذیر» وجود دارد:

اصلاح‌گرهای لایه

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

همچنین چندین روش ابزار داخلی برای رایج‌ترین انواع حاشیه وجود دارد. 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
            )
        )
    }
}

مصرف درج

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

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

در نتیجه، اصلاح‌کننده‌های بالشتک‌گذاری تودرتو به‌طور خودکار مقدار بالشتک‌گذاری اعمال‌شده روی هر عنصر ترکیبی را تغییر می‌دهند.

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

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

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

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

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

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

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

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

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 از حاشیه‌هایی که تحت تأثیر مصرف قرار نگرفته‌اند استفاده کنید. بااین‌حال، به‌دلیل هشدارهای زیر، درصورت امکان از اصلاح‌کننده‌های حاشیه پنجره و اصلاح‌کننده‌های اندازه حاشیه پنجره استفاده کنید.

حاشیه‌ها و مراحل Jetpack Compose

‫Compose از میاناهای برنامه‌سازی کاربردی اصلی AndroidX زیرین برای به‌روزرسانی و پویانمایی حاشیه‌ها استفاده می‌کند، که از میاناهای برنامه‌سازی کاربردی پلاتفرم زیرین برای مدیریت حاشیه‌ها استفاده می‌کنند. به‌دلیل رفتار آن پلاتفرم، حاشیه‌ها رابطه ویژه‌ای با مراحل Jetpack Compose دارند.

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