4. 使用Container与BoxDecoration绘制卡片UI

卡片视觉的四个可调层

Container 本身只是“布局容器”,真正决定卡片外观的是 BoxDecoration。把一张卡片拆开看,它由四层叠加而成:最外层是 margin(卡片与周围内容的间距),然后是 decoration 的阴影(boxShadow),再是渐变背景(gradient)与圆角(borderRadius),最内层是 padding(内容与卡片边缘的距离)。理解这四层的叠加顺序,就能独立调节每一层而不互相干扰。

卡片四层结构(由外到内) ① margin 卡片与外部内容的间距 ② boxShadow 阴影:color / blurRadius / offset ③ gradient + borderRadius 渐变背景与圆角裁剪 ④ padding 内容与卡片边缘的距离 child 内容区 BoxDecoration 关键参数 color / gradient:二选一,渐变优先 borderRadius:圆角半径 boxShadow:可叠加多层阴影 border:描边,与圆角同步裁剪 叠加顺序(先画 → 后画) 阴影 → 背景/渐变 → 边框 → 子内容 圆角同时作用于背景、边框与阴影 注意:color 与 gradient 同时设置时 gradient 会覆盖 color

完整可运行示例

下面这个卡片组件把四层参数都显式写出来,方便逐项调整观察效果。外层用 margin 控制卡片间距,decoration 负责圆角、阴影和渐变,padding 控制文字与边缘的距离。

import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: CardDemoPage()));

class CardDemoPage extends StatelessWidget {
  const CardDemoPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFFF7F9FC),
      body: Center(
        child: Container(
          // ① 外层间距:卡片与周围内容的距离
          margin: const EdgeInsets.all(24),
          // ④ 内边距:内容与卡片边缘的距离
          padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 18),
          // ②③ 装饰:阴影 + 渐变 + 圆角
          decoration: BoxDecoration(
            gradient: const LinearGradient(
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
              colors: [Color(0xFF5B8DEF), Color(0xFF8E6BF0)],
            ),
            borderRadius: BorderRadius.circular(20),
            boxShadow: const [
              BoxShadow(
                color: Color(0x473A4A6B),
                blurRadius: 12,
                offset: Offset(0, 6),
              ),
            ],
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: const [
              Text(
                'Flutter 实战',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
              ),
              SizedBox(height: 8),
              Text(
                'Container + BoxDecoration 卡片',
                style: TextStyle(color: Color(0xFFEAF0FF), fontSize: 13),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

参数调节与效果对照

改一个参数就能看出它控制哪一层。下表给出常用取值与视觉变化,便于按需微调。

参数示例值视觉变化
marginEdgeInsets.all(24)卡片四周留白增大,与屏幕边缘距离变远
paddingEdgeInsets.symmetric(h:20, v:18)文字与卡片边缘间距增大,卡片显得更“透气”
borderRadiusBorderRadius.circular(20)圆角变大,卡片更柔和;设为 0 则为直角
boxShadow.blurRadius12数值越大阴影越弥散,越小越锐利
boxShadow.offsetOffset(0, 6)正值向下偏移,形成“悬浮”感
gradient.colors[#5B8DEF, #8E6BF0]改变渐变两端颜色,决定卡片主色调
若卡片需要描边,在 BoxDecoration 中加 border: Border.all(color: Colors.white24, width: 1)。圆角会同时裁剪背景、边框和阴影,无需额外处理。
color 与 gradient 同时设置时,gradient 会覆盖 color,容易造成“改了颜色没反应”的困惑。二者只保留一个即可。

验证要点

  • 卡片四角为圆角,且阴影沿圆角轮廓分布,不出现直角阴影。
  • 背景为左上到右下的蓝紫渐变,文字为白色且与背景对比清晰。
  • 调整 margin 时卡片整体位置变化,调整 padding 时仅内部文字位置变化,二者互不影响。
  • 把 boxShadow 的 blurRadius 改为 0,阴影消失,可确认阴影确实来自该参数。