طرح بندی وضعیت میز با Grid و mediaQuery

نماد امتیاز ۴ ستاره

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

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

بهترین شیوه‌ها

برای افزودن پشتیبانی از حالت رومیزی به برنامه خود، از API Grid برای تعریف یک طرح‌بندی با دو ردیف و یک ستون استفاده کنید و کوئری رسانه‌ای حالت رومیزی پنجره را اعمال کنید.

  • تشخیص وضعیت میز به صورت واکنشی: از mediaQuery composable برای مشاهده وضعیت دستگاه استفاده کنید. هنگامی که دستگاه در وضعیت میز قرار می‌گیرد ( windowPosture == Posture.Tabletop )، طرح‌بندی خود را به صورت پویا و بدون نیاز به راه‌اندازی مجدد فعالیت یا مدیریت پیچیده چرخه عمر تغییر دهید.
  • ساختاربندی طرح‌بندی‌ها با Grid : وقتی در حالت رومیزی هستید، از API Grid ( 2 rows ، 1 column ) برای جداسازی دقیق محتوای بصری اصلی در ردیف بالای صفحه و کنترل‌های تعاملی در ردیف پایین زیر صفحه استفاده کنید.
  • استفاده از z-indexing ضمنی برای همپوشانی‌ها: در حالت‌های استاندارد (غیر رومیزی)، چندین شناسه ناحیه را به یک سلول اختصاص دهید تا کنترل‌های روی پخش‌کننده را همپوشانی کنید. Grid به طور خودکار آیتم‌ها را به ترتیب اعلانشان از عقب به جلو رندر می‌کند.
  • انتقال‌های روان را فراهم کنید: اطمینان حاصل کنید که موقعیت‌های حالت و اسکرول هنگام انتقال بین طرح‌بندی‌های استاندارد تمام صفحه و حالت رومیزی حفظ می‌شوند.

مواد لازم

  • Grid : یک ظرف طرح‌بندی تطبیقی ​​که به شما امکان می‌دهد موارد را در ردیف‌ها و ستون‌های قابل تنظیم قرار دهید، ایده‌آل برای تقسیم محتوا در مناطق مختلف صفحه نمایش.
  • mediaQuery : یک رابط برنامه‌نویسی کاربردی Jetpack Compose که برای پرس‌وجو از وضعیت فعلی پنجره، کلاس‌های اندازه و ویژگی‌های سخت‌افزاری برنامه مستقیماً درون composableهای شما استفاده می‌شود.

مراحل

با استفاده از mediaQuery() وضعیت دستگاه را بررسی کنید. وقتی دستگاه در وضعیت رومیزی قرار دارد، محتوای برنامه خود را در یک شبکه عمودی با دو ردیف و یک ستون مرتب کنید، مطمئن شوید که محتوای اصلی در بالا و کنترل‌ها در پایین قابل دسترسی هستند.

۱. تنظیمات شبکه‌ای را برای حالت رومیزی تعریف کنید

درون یک تابع قابل ترکیب، شناسه‌های ناحیه طرح‌بندی را با استفاده از یک enum تعریف کنید و بلوک‌های GridConfigurationScope را برای وضعیت‌های پیش‌فرض و رومیزی تنظیم کنید.

در defaultConfig ، هر دو ناحیه به یک سلول اختصاص داده شده‌اند ( row = 1, column = 1 ). Grid از z-indexing ضمنی استفاده می‌کند که در آن composableهایی که بعداً در طرح‌بندی تعریف شده‌اند، روی composableهای قبلی رندر می‌شوند و به کنترلر اجازه می‌دهند تا پخش‌کننده را بدون تودرتو کردن کانتینر اضافی، روی هم قرار دهد (برای جزئیات بیشتر به همپوشانی عناصر رابط کاربری با Grid مراجعه کنید).

enum class VideoPlayerArea { Player, Controller }

object PlayerGridConfig {
    // Default: Single area layout with overlay (controls on top of player)
    val defaultConfig: GridConfigurationScope.() -> Unit = {
        row(1f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1)
        area(areaId = VideoPlayerArea.Controller, row = 1, column = 1)
    }

    // Tabletop: Two rows splitting content across the fold
    val tabletopConfig: GridConfigurationScope.() -> Unit = {
        row(0.5f)
        row(0.5f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1) // Top half above fold
        area(areaId = VideoPlayerArea.Controller, row = 2, column = 1) // Bottom half below fold
    }
}

۲. تشخیص وضعیت میز و اعمال پیکربندی به Grid

از mediaQuery برای انتخاب پیکربندی فعال بر اساس windowPosture استفاده کنید، config به Grid منتقل کنید و محتوای قابل ترکیب را به شناسه‌های ناحیه متصل کنید. تعریف VideoPlayerArea.Player قبل از VideoPlayerArea.Controller تضمین می‌کند که وقتی هر دو یک سلول را در defaultConfig به اشتراک می‌گذارند، کنترل‌ها بالای پخش‌کننده رندر می‌شوند:

val config = mediaQuery {
    when (windowPosture) {
        Posture.Tabletop -> PlayerGridConfig.tabletopConfig
        else -> PlayerGridConfig.defaultConfig
    }
}

Grid(config = config) {
    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Player)
    ) {
        // VideoPlayerContent
    }

    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Controller)
    ) {
        // PlaybackControlsContent
    }
}

نتایج

با ترکیب mediaQuery و Grid ، برنامه شما به صورت پویا تشخیص می‌دهد که چه زمانی یک دستگاه تاشو تا حدی به حالت رومیزی تا شده است و به طور خودکار رابط کاربری آن را به دو ناحیه نمایش کاربردی که توسط تا شدن تقسیم شده‌اند، تنظیم می‌کند.

منابع اضافی