支付页面 UI 设计总览

支付页面是电商与金融类应用的核心转化漏斗,其布局结构、组件层级与响应能力直接影响用户付款成功率。本章从典型商用支付页面入手,拆解通用布局模式,逐层剥离 UI 组件,最终映射为 Jetpack Compose 组件树,为后续章节的代码实现提供静态结构基线。

典型布局分析

经过对 30+ 款主流支付页面(支付宝、微信支付、Stripe、Shopify 结账页)的抽样分析,支付页面布局可归纳为三种核心模式:

模式 典型特征 适用场景
单列纵向流 从上至下依次展开:品牌条、金额、支付方式列表、确认按钮、安全提示 移动端全屏展示,用户注意力引导明确
双栏并排 左侧支付选项(列表/卡片),右侧订单摘要 + 确认按钮 平板或桌面宽屏,减少滚动深度
嵌套抽屉 初始显示精简摘要,点击后展开支付方式详情/二维码 第三方唤起支付时快速返回到原有界面
选型提示:单列纵向流在 Compose 中使用 LazyColumn + stickyHeader 实现最为自然;双栏布局需避免嵌套垂直滚动,推荐使用 Row + 固定高度容器。

UI 组件层级拆解

支付页面从顶层到底层可拆解为 7 个主要层级。每个层级承担明确的 UI 职责与交互逻辑:

  1. 壳层(Shell):页面容器,处理系统状态栏、安全区域、全局加载/错误遮罩。
  2. 顶部导航:后退按钮、页面标题(如“确认付款”)、额外操作图标。
  3. 金额展示区:支付金额主数字、货币符号、金额说明(含/不含手续费提示)。
  4. 支付方式选择:单选卡片列表、新增卡入口、余额/积分开关。
  5. 订单信息摘要:商品名称、数量、小计、优惠券明细(可选折叠)。
  6. 确认按钮:主操作按钮、付款文案、加载状态(支付处理中)。
  7. 安全与法律声明:小字号安全标识、隐私协议链接、服务条款。
关键设计原则:每个层级尽量保持独立 ViewModel 状态槽位,避免跨层级状态耦合。金额展示区与支付方式选择区之间存在实时联动(如选择信用卡后金额旁显示手续费),应通过向上传递回调或共享 ViewModel 控制。

Compose 组件树构建

将上述层级映射到 Compose 可组合函数,形成清晰的组件树。节点按职责分组,父节点仅做布局编排,子节点持有具体交互逻辑。

// 伪代码:从壳到叶的组件树关系
PaymentScreen(
    onBackClick = { /* 返回处理 */ },
    onPay = { /* 支付回调 */ },
    modifier = Modifier.fillMaxSize()
) {
    val viewModel: PaymentViewModel = viewModel()

    // 壳层:Scaffold + Column
    Scaffold(topBar = { PaymentTopBar() }) { innerPadding ->
        Column(modifier = Modifier.padding(innerPadding)) {
            // 金额展示区
            AmountDisplay(
                amount = viewModel.amount,
                currency = "CNY",
                modifier = Modifier.fillMaxWidth()
            )
            // 支付方式选择区(内含单选列表)
            PaymentMethodSelector(
                methods = viewModel.methods,
                selectedMethod = viewModel.selectedMethod,
                onMethodSelected = { viewModel.selectMethod(it) }
            )
            // 订单摘要(可折叠)
            OrderSummary(order = viewModel.order)
            // 确认按钮(含加载状态)
            PayButton(
                isLoading = viewModel.isProcessing,
                enabled = viewModel.canPay,
                onClick = { viewModel.startPayment() }
            )
            // 安全声明
            SecurityNotice()
        }
    }
}
常见层级错误:将金额展示与支付方式选择直接耦合在同一个 Row 中,导致状态更新时整个 Row 重组。正确做法是使用 key 或 derivedStateOf 隔离重组范围,或拆分为独立的 @Composable 函数。

支付页面组件层级结构图

下图展示支付页面从壳层到叶节点的完整组件树,箭头表示父→子包含关系,虚线框表示可选/条件渲染组件:

支付页面 Compose 组件层级结构 PaymentScreen (壳层) Scaffold + Column PaymentTopBar AmountDisplay PaymentMethodSelector OrderSummary PayButton SecurityNotice MethodCard (×N) LoadingOverlay (可选) 说明:虚线框表示条件渲染组件,箭头颜色代表父节点分类。 实际开发中,Column 应使用 Modifier.verticalScroll() 或包裹在 LazyColumn 中处理长列表。 布局容器 导航组件 操作/展示组件 选择组件 信息摘要

调试与验证要点

在搭建组件树阶段,应通过 Compose 布局检查工具验证以下两点:

  • 嵌套深度:避免超过 10 层嵌套,否则会影响重组性能。使用 Layout Inspector 查看每个节点的重组次数。
  • 父级滚动冲突:若 PaymentMethodSelector 内部包含可滚动的 LazyColumn,其父容器 Column 必须换成 Box 固定高度,或启用 nestedScroll 协调。
性能陷阱:在组件树中,AmountDisplay 与 PayButton 若共用同一个 Column 并依赖 lambda 回传状态,容易导致不必要的重组。建议将这两个组件各自包裹在 remember 稳定的状态读取点中,或使用 derivedStateOf 隔离。

作业与自检

绘制你正在开发的支付页面的组件树,然后对照下表确认是否遗漏通用层级:

层级编号 必需性 常见遗漏
1 壳层(Screen容器) 必须 缺少系统状态栏安全边距处理
2 顶部导航 必须 无返回按钮(影响手势返回)
3 金额展示 必须 未显示货币符号或精度错误
4 支付方式选择 必须 缺少新增卡入口
5 订单摘要 推荐 优惠券信息不直观
6 确认按钮 必须 加载状态与正常状态未分离
7 安全声明 建议 经常被省略导致合规风险