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 属性速查
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
color | Color? | 白色 | 背景色 |
elevation | double? | 1 | 阴影高度 |
shadowColor | Color? | 黑色 | 阴影颜色 |
shape | ShapeBorder? | 圆角 4 | 形状 |
margin | EdgeInsetsGeometry? | 4 | 外边距 |
clipBehavior | Clip? | Clip.none | 裁剪行为 |
child | Widget? | null | 子组件 |
Chip 类型对比
| 类型 | 用途 | 交互 | 典型场景 |
|---|---|---|---|
Chip | 信息展示 | 删除 | 标签、联系人 |
InputChip | 输入/选择 | 选择 + 删除 | 邮箱收件人、标签选择 |
ActionChip | 触发操作 | 点击 | 快捷操作、筛选触发 |
FilterChip | 多选过滤 | 选择 | 标签多选、分类筛选 |
ChoiceChip | 单选 | 选择 | 尺寸选择、类型选择 |
Chip 通用属性速查
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
avatar | Widget? | null | 左侧头像/图标 |
label | Widget | 必填 | 标签文字 |
backgroundColor | Color? | 主题 | 背景色 |
selected | bool | false | 是否选中(InputChip/FilterChip/ChoiceChip) |
onDeleted | VoidCallback? | null | 删除回调(Chip/InputChip) |
onPressed | VoidCallback? | null | 点击回调(ActionChip) |
onSelected | ValueChanged<bool>? | null | 选中回调(InputChip/FilterChip/ChoiceChip) |
deleteIcon | Widget? | Icons.cancel | 删除图标 |
side | BorderSide? | null | 边框 |
shape | ShapeBorder? | 圆角 | 形状 |
快速示例
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) {}) // 单选