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

结尾

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

相关推荐
HelloBan2 小时前
setHintTextColor不生效
android
洞窝技术4 小时前
从0到30+:智能家居配网协议融合的实战与思考
android
QING6184 小时前
SupervisorJob子协程异常处理机制 —— 新手指南
android·kotlin·android jetpack
毕设源码-朱学姐5 小时前
【开题答辩全过程】以 基于安卓的停车位管理系统与设计为例,包含答辩的问题和答案
android
PWRJOY5 小时前
解决Flutter构建安卓项目卡在Flutter: Running Gradle task ‘assembleDebug‘...:替换国内 Maven 镜像
android·flutter·maven
王家视频教程图书馆6 小时前
android java 开发网路请求库那个好用请列一个排行榜
android·java·开发语言
花卷HJ6 小时前
Android 文件工具类 FileUtils(超全封装版)
android·java
Fate_I_C7 小时前
Kotlin 中的 suspend(挂起函数)
android·开发语言·kotlin
花卷HJ7 小时前
Android 下载管理器封装实战:支持队列下载、取消、进度回调与自动保存相册
android·java