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 也没有效果,不知道是什么原因。如果有解决方案,欢迎指正。

结尾

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

相关推荐
非凡ghost44 分钟前
PowerDirector安卓版(威力导演安卓版)
android·windows·学习·软件需求
独行soc1 小时前
2026年渗透测试面试题总结-19(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
爱装代码的小瓶子3 小时前
【C++与Linux基础】进程间通讯方式:匿名管道
android·c++·后端
兴趣使然HX3 小时前
Android绘帧流程解析
android
JMchen1234 小时前
Android UDP编程:实现高效实时通信的全面指南
android·经验分享·网络协议·udp·kotlin
黄林晴4 小时前
Android 17 再曝猛料:通知栏和快捷设置终于分家了,这操作等了十年
android
有位神秘人5 小时前
Android获取设备中本地音频
android·音视频
JMchen1235 小时前
Android网络安全实战:从HTTPS到双向认证
android·经验分享·网络协议·安全·web安全·https·kotlin
CS创新实验室5 小时前
Pandas 3 的新功能
android·ide·pandas
ujainu5 小时前
护眼又美观:Flutter + OpenHarmony 鸿蒙记事本一键切换夜间模式(四)
android·flutter·harmonyos