使用 Grid 和 mediaQuery 調整桌上型電腦的姿勢版面配置

4 星評分圖示

在摺疊式裝置上,桌上型電腦模式會將單一螢幕分割為兩個功能顯示區域,並以實體折疊處 (或轉軸) 分隔。 免手持模式可將應用程式的主要內容 (例如影片播放器或遊戲畫布) 放在上半部,互動式元素 (例如媒體遙控器或控制板) 則放在下半部。

摺疊式裝置處於免手持模式,上螢幕顯示影片內容,下螢幕顯示播放控制項。
圖 1. 桌上模式會將內容和互動控制項分割到實體摺疊處兩側。

最佳做法

如要為應用程式新增桌面模式支援,請使用 Grid API 定義含有兩列和一欄的版面配置,並套用桌面模式視窗姿勢媒體查詢。

  • 反應式偵測桌面模式:使用 mediaQuery 可組合函式觀察裝置狀態。將裝置摺疊成桌面模式 (windowPosture == Posture.Tabletop) 時,系統會動態調整版面配置,不必重新啟動活動或處理複雜的生命週期。
  • 使用 Grid 建立版面配置:在立架模式下,使用 Grid API (2 rows、1 column) 將主要視覺內容清楚分隔到摺疊線以上的頂端列,互動式控制項則分隔到摺疊線以下的底部列。
  • 運用疊加層的隱含 Z 索引:在標準 (非桌面) 姿勢中,將多個區域 ID 指派給同一個儲存格,在播放器上疊加控制項。Grid 會依宣告順序,自動將項目從後到前算繪。
  • 提供流暢的轉場效果:確保在標準全螢幕版面配置和桌上型電腦模式之間轉換時,狀態和捲動位置會保留不變。

要件

  • Grid:自動調整式版面配置容器,可讓您在可設定的列和欄中放置項目,非常適合將內容分割到不同的螢幕區域。
  • mediaQuery:Jetpack Compose API,用於直接在可組合函式中查詢應用程式目前的視窗姿勢、大小類別和硬體特徵。

步驟

使用 mediaQuery() 查詢裝置姿勢。如果裝置處於桌面型態,請將應用程式內容排列成垂直格線,包含兩列和一欄,確保主要內容位於頂端,控制項則位於底部,方便存取。

1. 定義平板電腦模式的格線設定

在可組合函式中,使用列舉定義版面配置區域 ID,並為預設和桌面模式設定 GridConfigurationScope 區塊。

在 defaultConfig 中,這兩個區域會指派給同一個儲存格 (row = 1, column = 1)。Grid 使用隱含的 z 索引,其中版面配置中稍後宣告的可組合函式會顯示在先前的函式上方,讓控制器覆蓋播放器,不必額外巢狀容器 (詳情請參閱「使用 Grid 疊加 UI 元素」)。

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
    }
}

2. 偵測免手持模式姿勢,並將設定套用至格線

使用 mediaQuery 根據 windowPosture 選取有效設定,將 config 傳遞至 Grid,並將可組合內容繫結至區域 ID。在 VideoPlayerArea.Controller 前宣告 VideoPlayerArea.Player,可確保兩者共用 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,應用程式就能動態偵測摺疊式裝置何時部分摺疊成桌面型態,並自動將 UI 調整為兩個功能顯示區域,以摺疊處為分界。

其他資源