Skip to content

Card & Chip

Card 是 Material 卡片容器,Chip 是标签/筹码组件。

构造函数

Card

dart
Card({
  Key? key,                                                        // 组件标识
  Color? color,                                                   // 背景色
  Color? shadowColor,                                             // 阴影颜色
  double? elevation,                                              // 阴影高度(默认 1)
  ShapeBorder? shape,                                             // 形状(默认圆角 4)
  bool borderOnForeground = true,                                 // 边框是否在前
  EdgeInsetsGeometry? margin,                                    // 外边距(默认 4)
  Clip? clipBehavior,                                            // 裁剪行为
  Widget? child,                                                  // 子组件
  bool semanticContainer = true,                                  // 语义容器
})

Card.outlined(M3)

dart
Card.outlined({                                                    // M3 边框卡片(无阴影)
  Key? key,
  Color? color,
  double? elevation = 0,                                          // 阴影高度固定为 0
  ShapeBorder? shape,
  bool borderOnForeground = true,
  EdgeInsetsGeometry? margin,
  Clip? clipBehavior,
  Widget? child,
  bool semanticContainer = true,
})

Card.filled(M3)

dart
Card.filled({                                                      // M3 填充卡片(无阴影)
  Key? key,
  Color? color,
  double? elevation = 0,
  ShapeBorder? shape,
  bool borderOnForeground = true,
  EdgeInsetsGeometry? margin,
  Clip? clipBehavior,
  Widget? child,
  bool semanticContainer = true,
})

Chip

dart
Chip({
  Key? key,                                                        // 组件标识
  Widget? avatar,                                                  // 左侧头像/图标
  required Widget label,                                           // 标签文字(必填)
  TextStyle? labelStyle,                                          // 标签样式
  EdgeInsetsGeometry? labelPadding,                               // 标签内边距
  Widget? deleteIcon,                                             // 删除图标
  Color? deleteIconColor,                                        // 删除图标颜色
  String? deleteButtonTooltipMessage,                            // 删除按钮提示
  VoidCallback? onDeleted,                                        // 删除回调
  Color? backgroundColor,                                        // 背景色
  Color? shadowColor,                                            // 阴影颜色
  double? elevation,                                             // 阴影高度
  EdgeInsetsGeometry? padding,                                   // 内边距
  VisualDensity? visualDensity,                                  // 视觉密度
  MaterialTapTargetSize? materialTapTargetSize,                  // 触摸目标大小
  ShapeBorder? shape,                                             // 形状
  BorderSide? side,                                              // 边框
  Clip clipBehavior = Clip.none,                                 // 裁剪行为
  bool autofocus = false,
  Color? focusColor,
  Color? hoverColor,
  FocusNode? focusNode,
})

InputChip

dart
InputChip({                                                        // 可交互的 Chip(选择/过滤)
  Key? key,
  Widget? avatar,
  required Widget label,
  TextStyle? labelStyle,
  EdgeInsetsGeometry? labelPadding,
  bool selected = false,                                          // 是否选中
  bool checkmarkColor,                                            // 选中标记颜色
  VoidCallback? onSelected,                                       // 选中回调
  Widget? deleteIcon,
  VoidCallback? onDeleted,
  Color? deleteIconColor,
  String? deleteButtonTooltipMessage,
  Color? backgroundColor,
  Color? selectedColor,                                           // 选中背景色
  Color? disabledColor,
  double? elevation,
  double? pressElevation,
  bool isEnabled = true,                                         // 是否启用
  EdgeInsetsGeometry? padding,
  VisualDensity? visualDensity,
  ShapeBorder? shape,
  BorderSide? side,
  Clip clipBehavior = Clip.none,
  FocusNode? focusNode,
  bool autofocus = false,
  Color? focusColor,
  Color? hoverColor,
})

ActionChip

dart
ActionChip({                                                       // 可点击操作的 Chip
  Key? key,
  Widget? avatar,
  required Widget label,
  TextStyle? labelStyle,
  VoidCallback? onPressed,                                        // 点击回调(必填)
  Color? backgroundColor,
  Color? shadowColor,
  double? elevation,
  double? pressElevation,
  VisualDensity? visualDensity,
  EdgeInsetsGeometry? padding,
  MaterialTapTargetSize? materialTapTargetSize,
  ShapeBorder? shape,
  BorderSide? side,
  Clip clipBehavior = Clip.none,
  FocusNode? focusNode,
  bool autofocus = false,
  Color? focusColor,
  Color? hoverColor,
})

FilterChip

dart
FilterChip({                                                       // 过滤选择 Chip
  Key? key,
  Widget? avatar,
  required Widget label,
  bool selected = false,
  VoidCallback? onSelected,
  Color? selectedColor,
  Color? disabledColor,
  double? elevation,
  double? pressElevation,
  bool isEnabled = true,
  EdgeInsetsGeometry? padding,
  VisualDensity? visualDensity,
  ShapeBorder? shape,
  BorderSide? side,
  Clip clipBehavior = Clip.none,
  FocusNode? focusNode,
  bool autofocus = false,
})

ChoiceChip

dart
ChoiceChip({                                                       // 单选 Chip
  Key? key,
  Widget? avatar,
  required Widget label,
  bool selected = false,
  VoidCallback? onSelected,
  Color? selectedColor,
  Color? disabledColor,
  double? elevation,
  double? pressElevation,
  bool isEnabled = true,
  EdgeInsetsGeometry? padding,
  ShapeBorder? visualDensity,
  ShapeBorder? shape,
  BorderSide? side,
  Clip clipBehavior = Clip.none,
  FocusNode? focusNode,
  bool autofocus = false,
})

属性速查

Card 属性速查

属性类型默认值说明
colorColor?白色背景色
elevationdouble?1阴影高度
shadowColorColor?黑色阴影颜色
shapeShapeBorder?圆角 4形状
marginEdgeInsetsGeometry?4外边距
clipBehaviorClip?Clip.none裁剪行为
childWidget?null子组件

Chip 类型对比

类型用途交互典型场景
Chip信息展示删除标签、联系人
InputChip输入/选择选择 + 删除邮箱收件人、标签选择
ActionChip触发操作点击快捷操作、筛选触发
FilterChip多选过滤选择标签多选、分类筛选
ChoiceChip单选选择尺寸选择、类型选择

Chip 通用属性速查

属性类型默认值说明
avatarWidget?null左侧头像/图标
labelWidget必填标签文字
backgroundColorColor?主题背景色
selectedboolfalse是否选中(InputChip/FilterChip/ChoiceChip)
onDeletedVoidCallback?null删除回调(Chip/InputChip)
onPressedVoidCallback?null点击回调(ActionChip)
onSelectedValueChanged<bool>?null选中回调(InputChip/FilterChip/ChoiceChip)
deleteIconWidget?Icons.cancel删除图标
sideBorderSide?null边框
shapeShapeBorder?圆角形状

快速示例

Card

dart
import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Card 示例')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          // 基本卡片
          // ─── ★ 基本卡片 ──────────────
          Card(
            child: Padding(
              padding: EdgeInsets.all(16),
              child: Text('卡片内容'),
            ),
          ),
          // ─── ☆ 基本卡片 ──────────────
          // 带阴影的卡片
          // ─── ★ 自定义阴影/圆角/边距 ──────────────
          Card(
            elevation: 8,
            shadowColor: Colors.blue.withOpacity(0.3),
            margin: EdgeInsets.all(16),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(12),
            ),
            child: Padding(
              padding: EdgeInsets.all(16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text('标题', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                  SizedBox(height: 8),
                  Text('描述文字'),
                ],
              ),
            ),
          ),
          // ─── ☆ 自定义阴影/圆角/边距 ──────────────
          // 列表卡片
          // ─── ★ Card + ListTile ──────────────
          Card(
            child: ListTile(
              leading: Icon(Icons.album),
              title: Text('歌曲名称'),
              subtitle: Text('歌手名'),
              trailing: Icon(Icons.more_vert),
              onTap: () {},
            ),
          ),
          // ─── ☆ Card + ListTile ──────────────
        ],
      ),
    );
  }
}

Chip

dart
import 'package:flutter/material.dart';

class ChipExample extends StatefulWidget {
  const ChipExample({super.key});

  @override
  State<ChipExample> createState() => _ChipExampleState();
}

class _ChipExampleState extends State<ChipExample> {
  bool isSelected = false;
  String selectedSize = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Chip 示例')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 基本标签
            // ─── ★ 基本 Chip ──────────────
            Chip(
              label: Text('Flutter'),
              avatar: CircleAvatar(child: Text('F')),
            ),
            // ─── ☆ 基本 Chip ──────────────
            // 可删除标签
            // ─── ★ onDeleted 可删除 ──────────────
            Chip(
              label: Text('标签'),
              onDeleted: () {},
              deleteIconColor: Colors.red,
            ),
            // ─── ☆ onDeleted 可删除 ──────────────
            // 可选标签(FilterChip - 多选)
            // ─── ★ 多选 FilterChip ──────────────
            FilterChip(
              label: Text('Dart'),
              selected: isSelected,
              onSelected: (selected) {
                setState(() => isSelected = selected);
              },
              selectedColor: Colors.blue.withOpacity(0.2),
            ),
            // ─── ☆ 多选 FilterChip ──────────────
            // 单选标签(ChoiceChip)
            // ─── ★ 单选 ChoiceChip ──────────────
            ChoiceChip(
              label: Text('Small'),
              selected: selectedSize == 'S',
              onSelected: (selected) {
                setState(() => selectedSize = 'S');
              },
            ),
            // ─── ☆ 单选 ChoiceChip ──────────────
          ],
        ),
      ),
    );
  }
}

Chip 列表(Wrap 布局)

dart
Wrap(
  spacing: 8,              // 水平间距
  runSpacing: 4,           // 垂直间距
  children: tags.map((tag) => Chip(
    label: Text(tag),
    onDeleted: () => setState(() => tags.remove(tag)),
  )).toList(),
)

ActionChip

dart
ActionChip(
  avatar: Icon(Icons.schedule, size: 18),
  label: Text('稍后提醒'),
  onPressed: () {
    // 触发操作
  },
)

常见错误

1. Card 内容溢出

dart
// ❌ 错误:Card 内 Column 内容溢出
Card(
  child: Column(
    children: [Text('A'), Text('B'), Text('C')],  // 可能溢出
  ),
)

// ✅ 修复:限制高度或使用 mainAxisSize: MainAxisSize.min
Card(
  child: Column(
    mainAxisSize: MainAxisSize.min,     // 自适应高度
    children: [Text('A'), Text('B')],
  ),
)

2. Chip 不响应点击

dart
// ❌ 错误:用了 Chip 但需要交互
Chip(label: Text('可点击'), onPressed: () {})   // Chip 没有 onPressed

// ✅ 修复:根据需求选择合适的 Chip 类型
ActionChip(label: Text('可点击'), onPressed: () {})    // 操作
FilterChip(label: Text('可选'), selected: true, onSelected: (v) {})  // 多选
ChoiceChip(label: Text('可选'), selected: true, onSelected: (v) {})  // 单选

基于 Flutter 官方文档整理