Administrator
发布于 2026-08-25 / 11 阅读
0
0

系列文章《Android 工程师的 100 篇进阶笔记》第 22 篇:Android 响应式 UI:WindowInsets、ConstraintLayout 与 Compose 适配

Android 设备形态越来越杂:折叠屏、平板、挖孔屏、刘海屏、药丸屏。只做一套固定布局已经不够了,响应式 UI 是高级工程师的必修课。


一、WindowInsets:处理好系统栏

ViewCompat.setOnApplyWindowInsetsListener(root) { view, insets ->
    val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
    view.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
    insets
}

WindowInsets 类型要分清:

  • systemBars():状态栏 + 导航栏

  • ime():软键盘

  • captionBar():标题栏

  • displayCutout():刘海/挖孔区域

  • tappableElement():可点击的系统元素

Compose 里用 WindowInsets:

val insets = WindowInsets.systemBars
val density = LocalDensity.current
Box(modifier = Modifier.padding(insets.asPaddingValues(density)))

二、ConstraintLayout 的百分比与引导线

<androidx.constraintlayout.widget.ConstraintLayout ...>

    <View
        android:id="@+id/sidebar"
        android:layout_width="0dp"
        app:layout_constraintWidth_percent="0.3"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.3" />

</androidx.constraintlayout.widget.ConstraintLayout>

ConstraintLayout 的百分比约束很适合大屏适配,不用写多套布局。


三、Compose 的响应式布局

@Composable
fun AdaptiveScreen() {
    val windowSizeClass = calculateWindowSizeClass(activity = activity)
    when (windowSizeClass.widthSizeClass) {
        WindowWidthSizeClass.Compact -> CompactLayout()
        WindowWidthSizeClass.Medium -> MediumLayout()
        WindowWidthSizeClass.Expanded -> ExpandedLayout()
    }
}

material3-window-size-class 把屏幕宽度分为 Compact、Medium、Expanded 三档,可以据此决定是单栏、双栏还是列表-详情布局。


四、折叠屏与多窗口

val foldingFeature = WindowInfoTracker.getOrCreate(context)
    .windowLayoutInfo(activity)
    .map { info ->
        info.displayFeatures.filterIsInstance<FoldingFeature>().firstOrNull()
    }

要处理:

  • 折叠态/展开态的页面切换

  • 多窗口模式下的生命周期

  • 配置变更(Configuration Change)时状态恢复


五、适配 checklist

  1. 状态栏/导航栏用 WindowInsets 处理,不要写死 padding

  2. 避免使用绝对像素,用 dp 和百分比

  3. 小屏用单栏,大屏用列表-详情

  4. 配置变更时保存状态,不要丢失用户输入

  5. 测试真机或模拟器的折叠、平板、分屏模式


小结

  1. WindowInsets 是现代 Android 处理系统栏的核心 API

  2. ConstraintLayout 百分比约束适合大屏

  3. Compose 用 WindowSizeClass 做响应式判断

  4. 折叠屏和多窗口需要专门测试

下一篇,我们聊聊模块化:Feature Module、Dynamic Delivery 与 App Bundle。


参考阅读

引用链接

[1]WindowInsets 兼容性指南: https://developer.android.com/develop/ui/views/layout/edge-to-edge

[2]Compose 响应式布局: https://developer.android.com/guide/topics/large-screens/large-screen-canonical-layouts


评论