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

结尾

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

相关推荐
dawudayudaxue9 分钟前
sqlite在安卓下使用ndk的交叉编译
android·数据库·sqlite
YIN_尹9 分钟前
【MySQL】表的约束(下)
android·数据库·mysql
爱编码的傅同学14 分钟前
【线程的同步与互斥】初识互斥量与锁
android·java·开发语言
_李小白18 分钟前
【Android 美颜相机】第十天:YUV420SP和RGB
android·数码相机
2501_9445264221 分钟前
Flutter for OpenHarmony 万能游戏库App实战 - 收藏功能实现
android·java·开发语言·javascript·python·flutter·游戏
2501_9445264222 分钟前
Flutter for OpenHarmony 万能游戏库App实战 - 个人中心实现
android·java·javascript·python·flutter·游戏
Jomurphys26 分钟前
Kotlin - 引用操作符 ::
android·kotlin
恋猫de小郭27 分钟前
Meta ShapeR :基于随机拍摄视频的 3D 物体生成,未来的 XR 和机器人基建支持
android·flutter·3d·ai·音视频·xr
2501_9159090610 小时前
如何保护 iOS IPA 文件中资源与文件的安全,图片、JSON重命名
android·ios·小程序·uni-app·json·iphone·webview
Root_Hacker11 小时前
include文件包含个人笔记及c底层调试
android·linux·服务器·c语言·笔记·安全·php