Android Jetpack Compose折叠屏感知与适配

前言

坚守安卓原生开发很久很久了,flutter 还是没有学会,所以目前依旧使用 Compose,资料不是很多,靠着官方文档和部分ai能力整理总结一下。

介绍

下面介绍一下屏幕感知会用到的类及其释义。

WindowSizeClass 窗口尺寸类别,用于标识窗口尺寸

完整包名:androidx.window.core.layout.WindowSizeClass,旗下有两个类:WindowWidthSizeClassWindowHeightSizeClass,分别对应宽度尺寸类别和高度尺寸类别,这两个类别会在屏幕旋转的时候变动,无需判断屏幕方向,只关心尺寸级别。

它们都有三种不同的尺寸级别枚举:

  • COMPACT:小尺寸
  • MEDIUM:中等尺寸
  • EXPANDED:大尺寸

尺寸详情请参考:官方文档

Posture 设备姿态

  • isTabletop:为 true 时,标识设备为笔记本电脑模式,像笔记本电脑一样放置,可根据这个状态针对性的绘制 ui 排版。

  • hingList:铰链信息列表,这里的铰链可能有多个,可以理解为:每一个可折叠部位,都视作一个铰链,举例:双折叠有一个铰链,三折叠有两个铰链。

HingeInfo 铰链

铰链是折叠屏感知中最核心的部分,可以根据不同形态的折叠屏进行精确的控制,字段如下:

  • bounds:铰链在屏幕当中的区域矩形,绘制 ui 时要,避开这些区域,通常情况下无遮挡铰链只有宽度或高度。
  • isOccluding:铰链区域是否会遮挡屏幕,如果遮挡,就需要搭配 bounds 字段调整 ui 绘制。
  • isFlat:屏幕完全展开时为 true
  • isSeparating:屏幕部分展开时为 true
  • isVertical:铰链是否为垂直放线,为 true 时,铰链是垂直方向,屏幕可以左右开合,为 false 时,铰链是水平方向,屏幕可以上下开合。

准备

首先,导入 Jetpack Compose BOM,下面以 toml 文件为例,版本 2025.12.00

ini 复制代码
[versions]
compose-bom = "2025.12.00"

[libraries]
# 主包必须要依赖
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" }

# 窗口感知和适配需要依赖的包
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-compose-material3-window-size = { group = "androidx.compose.material3", name = "material3-window-size-class" }
androidx-compose-material3-adaptive = { group = "androidx.compose.material3.adaptive", name = "adaptive" }
androidx-compose-material3-adaptive-layout = { group = "androidx.compose.material3.adaptive", name = "adaptive-layout" }

# 其他Compose包根据自己项目需要依赖,略

然后将声明好的包导入进项目 gradle 文件(Module 级别,以 kts 文件为例)

scss 复制代码
dependencies{
    //其他依赖,略

    //导入窗口感知依赖,如果跨包导入,使用api方法替换implementation方法
    implementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(platform(libs.androidx.compose.bom))
    api(libs.androidx.compose.material3)
    api(libs.androidx.compose.material3.window.size)
    api(libs.androidx.compose.material3.adaptive)
    api(libs.androidx.compose.material3.adaptive.layout)
}

核心逻辑

kotlin 复制代码
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import androidx.compose.runtime.Composable
import androidx.window.core.layout.WindowWidthSizeClass

@Compose
fun TestScreen(){
    //读取窗口信息
    val info = currentWindowAdaptiveInfo()

    //获取窗口尺寸类型
    val size = info.windowSizeClass

    //宽度尺寸判断
    when(size.windowWidthSizeClass){
        WindowWidthSizeClass.COMPATC -> {
            //todo 宽度,小
        }

        WindowWidthSizeClass.MEDIUM -> {
            //todo 宽度,中
        }

        WindowWidthSizeClass.EXPANDED -> {
            //todo 宽度,大
        }
    }

    //高度尺寸判断
    when(size.windowHeightSizeClass){
        WindowHeightSizeClass.COMPACT -> {
            //todo 高度,小
        }

        WindowHeightSizeClass.MEDIUM -> {
            //todo 高度,中
        }

        WindowHeightSizeClass.EXPANDED -> {
            //todo 高度,大
        }
    }


    //获取窗口姿态情况
    val posture = info.windowPosture

    //笔记本电脑姿态
    posture.isTabletop

    //获取铰链详情(只有折叠屏被打开时才有信息,否则hingeList为空)
    posture.hingeList.forEach { hinge ->
        //铰链在窗口中的区域(矩形)
        hinge.bounds

        //铰链区域是否会遮挡窗口
        hinge.isOccluding

        //完全展开(平摊状态)
        hinge.isFlat

        //部分展开(铰链打开、分离)
        hinge.isSeparating

        //铰链方向,true垂直,左右折叠;false水平,上下折叠
        hinge.isVertical
    }
}

要让每个界面都精确适配起来确实是个大工程,需要利用这些基础信息来做。

未解决的问题(可能)

去除 letterBox 窗口之后,即不限制屏幕旋转方向,会造成一定的适配问题,比如将一个竖屏的手机横放,此时宽度非常宽,但高度就很矮,像是登录界面就需要考虑换一种呈现方式,上下滑动的登录页面体验感大打折扣。我已经试过了在折叠屏关闭时,锁定屏幕方向,打开时解锁,但是会有生命周期的问题造成崩溃,因为旋转屏幕和展开屏幕都会重走生命周期,即使是配置 configChanges 也没有效果,不知道是什么原因。如果有解决方案,欢迎指正。

结尾

技术不高,水平有限,如有错误或不足,欢迎批评。

相关推荐
游戏开发爱好者81 小时前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
王码码20351 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
黑码哥1 小时前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
亓才孓2 小时前
[JDBC]元数据
android
独行soc2 小时前
2026年渗透测试面试题总结-17(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
金融RPA机器人丨实在智能2 小时前
Android Studio开发App项目进入AI深水区:实在智能Agent引领无代码交互革命
android·人工智能·ai·android studio
科技块儿2 小时前
利用IP查询在智慧城市交通信号系统中的应用探索
android·tcp/ip·智慧城市
独行soc2 小时前
2026年渗透测试面试题总结-18(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
王码码20353 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
2501_915106323 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview