引言
在 Flutter 开发中,基础布局、交互控件和视觉装饰组件是构建用户界面的核心。本文将深入讲解以下 6 个常用组件:
- Center:居中布局组件
- Checkbox:复选框控件
- Chip:标签/快捷操作组件
- CircularProgressIndicator:圆形进度指示器
- ClipOval:椭圆裁剪组件
- ClipPath:路径裁剪组件
1. Center:居中布局组件
用途:
Center 是最基础的布局组件之一,用于将其子组件在父容器中水平和垂直居中。
示例代码:
class CenterDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Center")),
body: Container(
color: Colors.grey[200],
child: Center(
child: Container(
width: 100,
height: 100,
color: Colors.blue,
child: Center(
child: Text(
"居中",
style: TextStyle(color: Colors.white),
),
),
),
),
),
);
}
}
核心参数:
- child 要居中的子组件
- widthFactor 宽度因子(如 2.0 表示宽度为子组件的 2 倍)
- heightFactor 高度因子(同上)
使用场景:
- 页面内容整体居中
- 加载状态提示居中
- 弹窗内容居中
- 图标与文本组合居中
2. Checkbox:复选框控件
用途:
Checkbox 用于实现二元选择(选中/未选中),常用于表单、设置项等。
示例代码:
class CheckboxDemo extends StatefulWidget {
@override
_CheckboxDemoState createState() => _CheckboxDemoState();
}
class _CheckboxDemoState extends State<CheckboxDemo> {
bool _isChecked = false;
List<String> _selectedItems = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Checkbox")),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
// 基础 Checkbox
Row(
children: [
Checkbox(
value: _isChecked,
onChanged: (bool? value) {
setState(() {
_isChecked = value!;
});
},
activeColor: Colors.blue, // 选中时的颜色
checkColor: Colors.white, // 对勾颜色
),
Text("我同意用户协议"),
],
),
SizedBox(height: 20),
// 列表中的 Checkbox
Text("选择兴趣:"),
...["编程", "设计", "音乐", "阅读"].map((item) {
return Row(
children: [
Checkbox(
value: _selectedItems.contains(item),
onChanged: (bool? value) {
setState(() {
if (value!) {
_selectedItems.add(item);
} else {
_selectedItems.remove(item);
}
});
},
),
Text(item),
],
);
}).toList(),
],
),
),
);
}
}
核心参数:
- value 当前是否选中(true/false/null 三态)
- onChanged 状态改变回调(传入 null 可实现三态)
- activeColor 选中时的背景色
- checkColor 对勾图标的颜色
- materialTapTargetSize 点击区域大小
使用场景:
- 表单中的“同意协议”选项
- 多选列表
- 设置开关(布尔值)
- 任务完成状态标记
3. Chip:标签/快捷操作组件
用途:
Chip 是 Material Design 中的标签组件,用于展示简短信息、过滤条件或快捷操作。Flutter 提供多种 Chip 类型:
- Chip:基本标签
- InputChip:输入建议
- ChoiceChip:单选标签组
- FilterChip:多选过滤标签
- ActionChip:操作按钮
示例代码:多种 Chip 类型
class ChipDemo extends StatefulWidget {
@override
_ChipDemoState createState() => _ChipDemoState();
}
class _ChipDemoState extends State<ChipDemo> {
bool _chipSelected = false;
String? _choiceChip;
Set<String> _filterChips = {};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Chip")),
body: Padding(
padding: EdgeInsets.all(16),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("1. 基础 Chip:"),
Wrap(
spacing: 8,
children: [
Chip(
label: Text("标签1"),
avatar: CircleAvatar(child: Text("1")),
onDeleted: () {},
deleteIcon: Icon(Icons.close, size: 16),
),
Chip(
label: Text("禁用"),
disabledColor: Colors.grey,
),
],
),
SizedBox(height: 20),
Text("2. ChoiceChip(单选):"),
Wrap(
spacing: 8,
children: ["A", "B", "C"].map((letter) {
return ChoiceChip(
label: Text(letter),
selected: _choiceChip == letter,
onSelected: (selected) {
setState(() {
_choiceChip = selected ? letter : null;
});
},
selectedColor: Colors.blue,
labelStyle: TextStyle(
color: _choiceChip == letter ? Colors.white : Colors.black,
),
);
}).toList(),
),
SizedBox(height: 20),
Text("3. FilterChip(多选):"),
Wrap(
spacing: 8,
children: ["React", "Vue", "Flutter"].map((tech) {
return FilterChip(
label: Text(tech),
selected: _filterChips.contains(tech),
onSelected: (selected) {
setState(() {
if (selected) {
_filterChips.add(tech);
} else {
_filterChips.remove(tech);
}
});
},
);
}).toList(),
),
SizedBox(height: 20),
Text("4. ActionChip:"),
ActionChip(
label: Text("点击执行操作"),
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("ActionChip 被点击")),
);
},
avatar: Icon(Icons.play_arrow),
),
],
),
),
),
);
}
}
使用场景:
- 搜索关键词标签
- 用户兴趣选择
- 筛选条件展示
- 快捷操作按钮
- 输入建议(InputChip)
4. CircularProgressIndicator:圆形进度指示器
用途:
CircularProgressIndicator 用于显示任务进度,分为确定进度和不确定进度两种模式。
示例代码:
class CircularProgressIndicatorDemo extends StatefulWidget {
@override
_CircularProgressIndicatorDemoState createState() =>
_CircularProgressIndicatorDemoState();
}
class _CircularProgressIndicatorDemoState
extends State<CircularProgressIndicatorDemo>
with SingleTickerProviderStateMixin {
double _progress = 0.0;
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: Duration(seconds: 2),
vsync: this,
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _startProgress() {
_progress = 0.0;
_controller.reset();
_controller.forward();
Timer.periodic(Duration(milliseconds: 50), (timer) {
setState(() {
_progress += 0.01;
if (_progress >= 1.0) {
_progress = 1.0;
timer.cancel();
}
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("CircularProgressIndicator")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 不确定进度(旋转动画)
Text("加载中..."),
SizedBox(height: 10),
CircularProgressIndicator(
strokeWidth: 4,
backgroundColor: Colors.grey[300],
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
SizedBox(height: 40),
// 确定进度
Text("确定进度:${(_progress * 100).toInt()}%"),
SizedBox(height: 10),
CircularProgressIndicator(
value: _progress,
strokeWidth: 8,
backgroundColor: Colors.grey[200],
valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _startProgress,
child: Text("开始进度"),
),
],
),
),
);
}
}
核心参数:
value 进度值(null 为不确定,0.0~1.0 为确定)
strokeWidth 圆环宽度
backgroundColor 背景圆环颜色
valueColor 进度圆环颜色(通常用 AlwaysStoppedAnimation)
使用场景:
- 网络请求加载状态
- 文件上传/下载进度
- 初始化等待
- 页面刷新指示
5. ClipOval:椭圆裁剪组件
用途:
ClipOval 用于将子组件裁剪为椭圆形或圆形,常用于头像、图标等。
示例代码:
class ClipOvalDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("ClipOval")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 圆形头像
ClipOval(
child: Image.network(
'https://source.unsplash.com/random/200x200?face',
width: 100,
height: 100,
fit: BoxFit.cover,
),
),
SizedBox(height: 30),
// 椭圆图片
ClipOval(
child: Container(
width: 150,
height: 100,
color: Colors.blue,
alignment: Alignment.center,
child: Text(
"椭圆",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
],
),
),
);
}
}
使用场景:
- 用户头像(圆形)
- 图标圆形背景
- 椭圆按钮
- 装饰性裁剪
6. ClipPath:路径裁剪组件
用途:
ClipPath 允许你使用自定义的 Path 来裁剪子组件,实现任意形状的裁剪效果。
示例代码:三角形裁剪
class TriangleClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final path = Path();
path.moveTo(size.width / 2, 0); // 顶部中点
path.lineTo(size.width, size.height); // 右下角
path.lineTo(0, size.height); // 左下角
path.close(); // 闭合路径
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}
class ClipPathDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("ClipPath")),
body: Center(
child: ClipPath(
clipper: TriangleClipper(),
child: Container(
width: 200,
height: 200,
color: Colors.red,
alignment: Alignment.center,
child: Text(
"三角形",
style: TextStyle(color: Colors.white, fontSize: 20),
),
),
),
),
);
}
}
示例:波浪形裁剪
class WaveClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
final path = Path();
path.lineTo(0, size.height - 20);
path.quadraticBezierTo(
size.width / 2,
size.height,
size.width,
size.height - 20,
);
path.lineTo(size.width, 0);
path.close();
return path;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => false;
}
核心参数:
clipper 自定义 CustomClipper<Path>
child 被裁剪的子组件
clipBehavior 裁剪行为(hardEdge、antiAlias 等)
使用场景:
- 自定义形状头像/按钮
- 波浪形背景
- 切角卡片
- 装饰性 UI 元素
最佳实践建议
- 使用 Center 快速实现居中布局。
- 使用 Checkbox 构建表单和设置项。
- 使用 Chip 管理标签、筛选和快捷操作。
- 使用 CircularProgressIndicator 提供加载反馈。
- 使用 ClipOval 快速实现圆形头像。
- 使用 ClipPath 实现自定义形状,提升 UI 美感。










网友评论