折叠屏适配

72 阅读2分钟

一、理解折叠屏设备特性

  1. 屏幕状态

    • 折叠(Closed / Half-open) :小屏(Cover Screen)
    • 展开(Opened) :大屏(Main Screen)
  2. 屏幕尺寸与比例差异大

    • 折叠后通常为普通手机尺寸(如 6 英寸)
    • 展开后可能接近平板(如 8 英寸以上),且长宽比可能非常规(如 6:5、4:3)
  3. 铰链区域(Hinge)

    • 某些设备(如 Surface Duo)存在物理缝隙或非连续显示区域
    • 可通过 displayCutoutWindowInsets 获取相关信息

##二、适配策略

1. 响应式布局(Responsive Layout)

使用 ConstraintLayoutFragmentsJetpack Compose 等支持动态布局的技术。

  • 使用 res/layout-sw600dp/ 等资源限定符区分小屏/大屏布局
  • 避免硬编码尺寸,使用 wrap_contentmatch_parentweightGuideline
<!-- res/layout/activity_main.xml --> <!-- 手机 -->
<!-- res/layout-sw600dp/activity_main.xml --> <!-- 平板/展开态 -->

2. 监听屏幕折叠状态变化

从 Android 10(API 29)起,可通过 Configuration Changes 监听折叠状态:

方法一:监听 configChanges

AndroidManifest.xml 中声明:

<activity
    android:name=".MainActivity"
    android:configChanges="screenSize|smallestScreenSize|screenLayout"
    android:exported="true">
</activity>

在 Activity 中重写:

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    // 检查当前是否为大屏
    if (newConfig.smallestScreenWidthDp >= 600) {
        // 大屏布局逻辑
    } else {
        // 小屏布局逻辑
    }
}

对于一些自定义view,可以在onViewAttachToWindow中重新计算尺寸。

方法二:使用 Jetpack WindowManager(推荐)

Google 推荐使用 Jetpack WindowManager 库来处理折叠设备。

添加依赖:

implementation "androidx.window:window:1.3.0"

监听折叠状态:

val windowInfoRepo = WindowInfoTracker.getOrCreate(this)
lifecycleScope.launch(Dispatchers.Main) {
    windowInfoRepo.windowLayoutInfo(this@MainActivity)
        .collect { layoutInfo ->
            val foldFeatures = layoutInfo.displayFeatures.filterIsInstance<FoldingFeature>()
            if (foldFeatures.isNotEmpty()) {
                val state = foldFeatures[0].state // STATE_FLAT (展开) / STATE_HALF_OPENED (半开)
                val isFolded = state == FoldingFeature.State.HALF_OPENED
                // 根据状态调整 UI
            }
        }
}

3. 多窗口与连续性体验

  • 不要阻止多窗口模式:避免设置 resizeableActivity="false"
  • 保存状态:确保在屏幕切换时 UI 状态不丢失(使用 ViewModel + SavedStateHandle)
  • 任务连续性:用户从折叠切换到展开时,应保持当前操作上下文(如正在编辑的表单、播放的视频等)

4. 测试

  • 使用 Android Studio 自带的 Device Manager 创建折叠屏模拟器(如 “Galaxy Fold”)
  • 在真实设备上测试(如 Pixel Fold、三星 Fold 系列)
  • 使用 adb 命令模拟折叠状态(需配合 WindowManager 支持):
# 模拟折叠
adb shell wm set-folding-feature-state 0 STATE_HALF_OPENED

# 模拟展开
adb shell wm set-folding-feature-state 0 STATE_FLAT

注意:该命令仅在支持 WindowManager 的设备/模拟器上有效。


三、进阶优化

  • 分屏双窗交互:在大屏上可采用主-详(Master-Detail)布局
  • 拖拽与跨区域交互:利用大屏空间实现更丰富的手势操作
  • 避免 UI 被铰链遮挡:通过 FoldingFeature.bounds 获取铰链区域,避开关键控件
val hingeBounds = foldFeature.bounds
// 调整布局 margin 或使用 Guideline 避开该区域