基础入门 Flutter for OpenHarmony:Icon 图标组件详解
在移动应用开发中,图标(Icon)是最基础也是最重要的视觉元素之一。一个好的图标能够直观地传达功能含义,提升用户体验,减少用户的学习成本。Flutter 提供了强大而灵活的 Icon 组件,让开发者能够轻松地在应用中使用各种图标。在开始学习 Icon 组件之前,我们需要先了解 Flutter 的图标系统。Flutter 提供了多种图标来源,每种都有其特点和适用场景。字体图标:通过 iconfont

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
🎯 欢迎来到 Flutter for OpenHarmony 社区!本文将深入讲解 Flutter 中 Icon 图标组件的使用方法,带你从基础到精通,掌握这一最常见的视觉元素。
一、Icon 组件概述
在移动应用开发中,图标(Icon)是最基础也是最重要的视觉元素之一。一个好的图标能够直观地传达功能含义,提升用户体验,减少用户的学习成本。Flutter 提供了强大而灵活的 Icon 组件,让开发者能够轻松地在应用中使用各种图标。
📋 Icon 组件特点
| 特点 | 说明 |
|---|---|
| 矢量图形 | 基于矢量绘制,任意缩放不失真 |
| 丰富图标库 | 内置数千个 Material Design 和 Cupertino 图标 |
| 高度可定制 | 支持颜色、大小、语义标签等属性 |
| 性能优异 | 矢量渲染,内存占用小,加载速度快 |
| 无障碍支持 | 支持语义化标签,方便屏幕阅读器识别 |
为什么图标如此重要?
图标在用户界面设计中扮演着不可或缺的角色。一个优秀的图标设计能够带来以下好处:
- 快速识别:用户可以通过图标快速识别功能,比阅读文字更高效
- 节省空间:图标占用空间小,可以在有限的屏幕空间内展示更多功能
- 跨语言通用:好的图标设计可以跨越语言障碍,全球用户都能理解
- 视觉美感:精心设计的图标可以提升应用的整体视觉品质
- 品牌识别:独特的图标风格可以成为品牌的一部分
💡 使用场景:图标广泛应用于导航栏、工具栏、列表项、按钮、标签页等各种 UI 组件中,是构建用户界面的基础元素。
二、Flutter 图标系统简介
在开始学习 Icon 组件之前,我们需要先了解 Flutter 的图标系统。Flutter 提供了多种图标来源,每种都有其特点和适用场景。
2.1 Material Design 图标
Material Design 图标是 Flutter 默认提供的图标库,包含了数千个符合 Material Design 规范的图标。这些图标涵盖了常见的各种场景,如导航、操作、通信、文件、设备等。
Material 图标的分类:
| 分类 | 说明 | 示例图标 |
|---|---|---|
| Action | 操作类图标 | home, search, settings |
| Alert | 提示类图标 | error, warning, info |
| AV | 音视频类图标 | play, pause, volume_up |
| Communication | 通信类图标 | email, phone, message |
| Content | 内容类图标 | add, edit, delete |
| Device | 设备类图标 | camera, wifi, bluetooth |
| File | 文件类图标 | folder, description, attach_file |
| Hardware | 硬件类图标 | keyboard, mouse, printer |
| Image | 图像类图标 | image, photo, camera_alt |
| Maps | 地图类图标 | map, location_on, directions |
| Navigation | 导航类图标 | menu, arrow_back, close |
| Places | 场所类图标 | home, work, restaurant |
| Social | 社交类图标 | person, group, share |
2.2 Cupertino 图标
Cupertino 图标是 iOS 风格的图标库,适用于需要模仿 iOS 设计风格的应用。这些图标与 iOS 系统图标保持一致,让 iOS 用户感到熟悉。
Cupertino 图标的特点:
- 线条更细,更符合 iOS 的设计语言
- 包含 iOS 特有的图标,如 SF Symbols 风格
- 需要单独引入
cupertino_icons包
2.3 自定义图标
除了使用内置图标,Flutter 还支持使用自定义图标:
- 字体图标:通过 iconfont 等工具生成的字体文件
- SVG 图标:通过
flutter_svg包加载 SVG 格式图标 - 图片图标:使用 PNG、JPG 等图片格式作为图标
三、Icon 基础用法
了解了 Flutter 的图标系统后,让我们开始学习 Icon 组件的基本使用方法。Icon 组件的使用非常简单,但掌握其各种属性可以让你创建出更加精美的界面。
3.1 最简单的 Icon
最基础的 Icon 只需要一个参数:icon(图标数据)。
Icon(Icons.home)
代码解析:
Icons.home:这是 Flutter 提供的 Material Design 图标之一,表示"首页"图标Icon组件会使用默认的颜色和大小来渲染这个图标
3.2 指定图标大小
通过 size 属性可以控制图标的显示大小。
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(Icons.star, size: 16),
Icon(Icons.star, size: 24),
Icon(Icons.star, size: 32),
Icon(Icons.star, size: 48),
],
)
尺寸选择建议:
| 尺寸 | 适用场景 |
|---|---|
| 16dp | 小型图标,如列表项辅助图标 |
| 24dp | 标准图标,工具栏、导航栏 |
| 32dp | 中等图标,突出显示的功能 |
| 48dp | 大型图标,空状态插图 |
| 64dp+ | 特大图标,启动页、Logo |
3.3 设置图标颜色
通过 color 属性可以设置图标的颜色。图标颜色应该与应用的整体配色方案保持一致。
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(Icons.favorite, color: Colors.red),
Icon(Icons.favorite, color: Colors.pink),
Icon(Icons.favorite, color: Colors.purple),
Icon(Icons.favorite, color: Colors.blue),
],
)
颜色使用原则:
- 功能性颜色:红色表示错误或删除,绿色表示成功,黄色表示警告
- 主题一致性:图标颜色应与应用主题色协调
- 可读性:确保图标颜色与背景色有足够的对比度
- 语义化:相同功能的图标应使用相同的颜色
3.4 完整示例
下面是一个完整的可运行示例,展示了 Icon 组件的基本使用:
class IconExample extends StatelessWidget {
const IconExample({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Icon 示例')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.home,
size: 48,
color: Colors.blue,
),
const SizedBox(height: 16),
const Text(
'这是一个首页图标',
style: TextStyle(fontSize: 18),
),
const SizedBox(height: 32),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildIconWithLabel(Icons.phone, '电话', Colors.green),
_buildIconWithLabel(Icons.message, '消息', Colors.blue),
_buildIconWithLabel(Icons.camera, '相机', Colors.orange),
_buildIconWithLabel(Icons.settings, '设置', Colors.grey),
],
),
],
),
),
);
}
Widget _buildIconWithLabel(IconData icon, String label, Color color) {
return Column(
children: [
Icon(icon, size: 32, color: color),
const SizedBox(height: 8),
Text(label, style: TextStyle(color: color)),
],
);
}
}
四、Icon 常用属性详解
掌握了基础用法后,我们来深入了解 Icon 的各种属性。这些属性可以帮助我们更好地控制图标的外观和行为。
4.1 icon - 图标数据
icon 是 Icon 组件的核心属性,用于指定要显示的图标。它接收一个 IconData 类型的值。
Icon(Icons.home)
Icon(Icons.search)
Icon(Icons.person)
Icon(Icons.settings)
常用图标速查:
| 图标 | 代码 | 用途 |
|---|---|---|
| 🏠 | Icons.home | 首页 |
| 🔍 | Icons.search | 搜索 |
| ➕ | Icons.add | 添加 |
| ✏️ | Icons.edit | 编辑 |
| 🗑️ | Icons.delete | 删除 |
| ⚙️ | Icons.settings | 设置 |
| 👤 | Icons.person | 用户 |
| ❤️ | Icons.favorite | 收藏 |
| ⭐ | Icons.star | 星标 |
| 📧 | Icons.email | 邮件 |
| 📞 | Icons.phone | 电话 |
| 📷 | Icons.camera | 相机 |
4.2 size - 图标大小
size 属性控制图标的显示尺寸,单位是逻辑像素(dp)。
Icon(Icons.star, size: 24) // 小图标
Icon(Icons.star, size: 48) // 中等图标
Icon(Icons.star, size: 72) // 大图标
深入理解尺寸:
- Flutter 中的尺寸单位是逻辑像素(dp),会自动适配不同屏幕密度
- Material Design 建议的标准图标尺寸是 24dp
- 图标尺寸应该与周围的文字大小协调
4.3 color - 图标颜色
color 属性设置图标的颜色。图标会以单一颜色渲染,颜色会填充图标的可见区域。
Icon(Icons.favorite, color: Colors.red)
Icon(Icons.favorite, color: Color(0xFFFF5722))
Icon(Icons.favorite, color: Theme.of(context).primaryColor)
颜色设置技巧:
- 使用
Colors类提供的预定义颜色,方便快捷 - 使用
Color(0xFFRRGGBB)格式可以指定任意颜色 - 使用
Theme.of(context).primaryColor可以获取主题色,保持一致性 - 使用
withOpacity()可以设置透明度
4.4 semanticLabel - 语义标签
semanticLabel 属性为图标提供无障碍描述,用于屏幕阅读器朗读。这对于视障用户非常重要。
Icon(
Icons.favorite,
semanticLabel: '收藏按钮',
)
无障碍设计原则:
- 所有功能性图标都应该提供语义标签
- 语义标签应该简洁明了,描述图标的功能而非外观
- 避免使用"图标"、"图片"等冗余词汇
4.5 textDirection - 文本方向
textDirection 属性控制图标的渲染方向,主要用于支持从右到左(RTL)的语言环境。
Icon(
Icons.arrow_back,
textDirection: TextDirection.ltr,
)
国际化考虑:
- 大多数图标不需要特别设置此属性
- 对于方向敏感的图标(如箭头),需要根据语言环境调整
- Flutter 会自动处理大多数 RTL 场景
📊 Icon 属性速查表
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| icon | IconData | - | 图标数据(必填) |
| size | double? | - | 图标大小 |
| color | Color? | - | 图标颜色 |
| semanticLabel | String? | - | 语义标签 |
| textDirection | TextDirection? | - | 文本方向 |
| shadows | List<Shadow>? | - | 阴影效果 |
五、IconButton 图标按钮
除了基本的 Icon 组件,Flutter 还提供了 IconButton 组件,它是一个可点击的图标按钮。IconButton 结合了图标和按钮的功能,是工具栏和操作栏中常用的组件。
5.1 基础用法
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
print('搜索按钮被点击');
},
)
IconButton 与 Icon 的区别:
| 特性 | Icon | IconButton |
|---|---|---|
| 可点击 | 否 | 是 |
| 点击效果 | 无 | 有水波纹效果 |
| 使用场景 | 纯展示 | 交互操作 |
| 默认大小 | 跟随 size 属性 | 固定 48dp 触摸区域 |
5.2 常用属性
IconButton(
icon: const Icon(Icons.favorite),
iconSize: 32,
color: Colors.red,
tooltip: '收藏',
onPressed: () {
print('收藏按钮被点击');
},
)
属性说明:
icon:要显示的图标iconSize:图标大小color:图标颜色tooltip:长按提示文本onPressed:点击回调,设为 null 时按钮禁用
5.3 完整工具栏示例
class ToolbarExample extends StatelessWidget {
const ToolbarExample({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('IconButton 示例'),
actions: [
IconButton(
icon: const Icon(Icons.search),
tooltip: '搜索',
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('搜索功能')),
);
},
),
IconButton(
icon: const Icon(Icons.favorite),
tooltip: '收藏',
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('收藏功能')),
);
},
),
IconButton(
icon: const Icon(Icons.more_vert),
tooltip: '更多',
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('更多选项')),
);
},
),
],
),
body: const Center(
child: Text('点击右上角的图标按钮'),
),
);
}
}
六、IconTheme 图标主题
在实际开发中,我们通常希望应用中的所有图标保持一致的风格。Flutter 提供了 IconTheme 组件,可以统一设置子树中所有图标的默认样式。
6.1 为什么需要 IconTheme?
想象一下,如果你的应用有 100 个图标,每个都需要设置相同的颜色和大小,那将会是多么繁琐的工作。IconTheme 可以让你一次性设置所有图标的默认样式,大大提高开发效率。
6.2 基础用法
IconTheme(
data: IconThemeData(
color: Colors.blue,
size: 32,
),
child: Row(
children: [
Icon(Icons.home),
Icon(Icons.search),
Icon(Icons.person),
Icon(Icons.settings),
],
),
)
IconThemeData 属性:
| 属性 | 类型 | 说明 |
|---|---|---|
| color | Color? | 图标颜色 |
| size | double? | 图标大小 |
| opacity | double? | 图标透明度 |
| shadows | List<Shadow>? | 阴影效果 |
6.3 全局图标主题
在 MaterialApp 中设置全局图标主题:
MaterialApp(
theme: ThemeData(
iconTheme: const IconThemeData(
color: Colors.blue,
size: 24,
),
),
home: const MyHomePage(),
)
七、常用图标分类速查
为了方便开发者快速找到需要的图标,下面按照功能分类列出常用的 Material Design 图标。
7.1 导航类图标
| 图标 | 代码 | 用途 |
|---|---|---|
| 🏠 | Icons.home | 首页 |
| ← | Icons.arrow_back | 返回 |
| → | Icons.arrow_forward | 前进 |
| ☰ | Icons.menu | 菜单 |
| ✕ | Icons.close | 关闭 |
| ⋮ | Icons.more_vert | 更多(垂直) |
| ⋯ | Icons.more_horiz | 更多(水平) |
7.2 操作类图标
| 图标 | 代码 | 用途 |
|---|---|---|
| ➕ | Icons.add | 添加 |
| ✏️ | Icons.edit | 编辑 |
| 🗑️ | Icons.delete | 删除 |
| ✓ | Icons.check | 确认 |
| ✕ | Icons.close | 取消 |
| 💾 | Icons.save | 保存 |
| 📋 | Icons.copy | 复制 |
| 📤 | Icons.share | 分享 |
7.3 状态类图标
| 图标 | 代码 | 用途 |
|---|---|---|
| ✓ | Icons.check_circle | 成功 |
| ⚠️ | Icons.warning | 警告 |
| ❌ | Icons.error | 错误 |
| ℹ️ | Icons.info | 信息 |
| ❓ | Icons.help | 帮助 |
7.4 社交类图标
| 图标 | 代码 | 用途 |
|---|---|---|
| 👤 | Icons.person | 用户 |
| 👥 | Icons.group | 群组 |
| ❤️ | Icons.favorite | 收藏 |
| ⭐ | Icons.star | 星标 |
| 📧 | Icons.email | 邮件 |
| 📞 | Icons.phone | 电话 |
| 💬 | Icons.message | 消息 |
7.5 媒体类图标
| 图标 | 代码 | 用途 |
|---|---|---|
| ▶️ | Icons.play_arrow | 播放 |
| ⏸️ | Icons.pause | 暂停 |
| ⏹️ | Icons.stop | 停止 |
| 📷 | Icons.camera | 相机 |
| 🖼️ | Icons.image | 图片 |
| 🎵 | Icons.music_note | 音乐 |
| 🎬 | Icons.movie | 视频 |
八、实际应用场景
8.1 底部导航栏
图标在底部导航栏中应用广泛,每个标签页都需要一个图标来表示其功能。
class BottomNavExample extends StatefulWidget {
const BottomNavExample({super.key});
State<BottomNavExample> createState() => _BottomNavExampleState();
}
class _BottomNavExampleState extends State<BottomNavExample> {
int _currentIndex = 0;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('底部导航栏示例')),
body: Center(
child: Text('当前页面: ${_currentIndex + 1}'),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: '搜索',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: '我的',
),
],
),
);
}
}
8.2 列表项图标
在列表中使用图标可以帮助用户快速识别每个选项的功能。
class ListIconExample extends StatelessWidget {
const ListIconExample({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('列表图标示例')),
body: ListView(
children: [
ListTile(
leading: const Icon(Icons.phone, color: Colors.green),
title: const Text('电话'),
subtitle: const Text('拨打电话'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () {},
),
ListTile(
leading: const Icon(Icons.email, color: Colors.blue),
title: const Text('邮件'),
subtitle: const Text('发送邮件'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () {},
),
ListTile(
leading: const Icon(Icons.location_on, color: Colors.red),
title: const Text('位置'),
subtitle: const Text('查看位置'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () {},
),
],
),
);
}
}
8.3 空状态图标
当页面没有内容时,使用大图标配合文字提示用户。
class EmptyStateExample extends StatelessWidget {
const EmptyStateExample({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('空状态示例')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.inbox,
size: 80,
color: Colors.grey[300],
),
const SizedBox(height: 16),
Text(
'暂无内容',
style: TextStyle(
fontSize: 18,
color: Colors.grey[500],
),
),
const SizedBox(height: 8),
Text(
'下拉刷新或点击添加新内容',
style: TextStyle(
fontSize: 14,
color: Colors.grey[400],
),
),
],
),
),
);
}
}
九、最佳实践与注意事项
9.1 图标选择原则
- 语义清晰:图标应该能够直观地表达其功能含义
- 风格统一:同一应用中的图标风格应保持一致
- 大小适中:图标大小应与周围元素协调
- 颜色合理:图标颜色应符合功能语义和应用主题
9.2 无障碍设计
- 为功能性图标添加
semanticLabel - 确保图标颜色与背景有足够对比度
- 不要仅依赖图标传达信息,配合文字说明
- 为 IconButton 添加
tooltip提示
9.3 性能优化
- 优先使用内置图标,避免加载外部资源
- 对于大量图标,使用 IconTheme 统一管理
- 避免在动画中频繁改变图标颜色
9.4 常见问题
问题 1:图标显示为方框
原因:使用了不存在的图标名称
解决:检查图标名称是否正确,参考官方图标列表
问题 2:图标颜色不生效
原因:可能被 IconTheme 或主题覆盖
解决:检查父组件是否设置了 IconTheme
问题 3:图标模糊
原因:图标尺寸过大或过小
解决:使用合适的尺寸,Material Design 建议使用 24dp
十、完整代码示例
下面是一个完整的、可以直接运行的 main.dart 文件,展示了 Icon 组件的各种用法:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Icon 组件示例',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const IconDemoPage(),
);
}
}
class IconDemoPage extends StatefulWidget {
const IconDemoPage({super.key});
State<IconDemoPage> createState() => _IconDemoPageState();
}
class _IconDemoPageState extends State<IconDemoPage> {
int _currentIndex = 0;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Icon 图标组件详解'),
actions: [
IconButton(
icon: const Icon(Icons.search),
tooltip: '搜索',
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('搜索功能')),
);
},
),
IconButton(
icon: const Icon(Icons.notifications),
tooltip: '通知',
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('通知功能')),
);
},
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSection('一、基础图标', [
const Text('最简单的图标使用:'),
const SizedBox(height: 12),
Wrap(
spacing: 24,
runSpacing: 16,
children: [
_buildIconItem(Icons.home, '首页'),
_buildIconItem(Icons.search, '搜索'),
_buildIconItem(Icons.person, '用户'),
_buildIconItem(Icons.settings, '设置'),
_buildIconItem(Icons.favorite, '收藏'),
_buildIconItem(Icons.star, '星标'),
],
),
]),
const Divider(height: 32),
_buildSection('二、不同尺寸', [
const Text('通过 size 属性控制图标大小:'),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildIconWithSize(Icons.star, 16, '16dp'),
_buildIconWithSize(Icons.star, 24, '24dp'),
_buildIconWithSize(Icons.star, 32, '32dp'),
_buildIconWithSize(Icons.star, 48, '48dp'),
_buildIconWithSize(Icons.star, 64, '64dp'),
],
),
]),
const Divider(height: 32),
_buildSection('三、不同颜色', [
const Text('通过 color 属性设置图标颜色:'),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildIconWithColor(Icons.favorite, Colors.red, '红色'),
_buildIconWithColor(Icons.favorite, Colors.pink, '粉色'),
_buildIconWithColor(Icons.favorite, Colors.purple, '紫色'),
_buildIconWithColor(Icons.favorite, Colors.blue, '蓝色'),
_buildIconWithColor(Icons.favorite, Colors.green, '绿色'),
],
),
]),
const Divider(height: 32),
_buildSection('四、IconButton 图标按钮', [
const Text('可点击的图标按钮:'),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
icon: const Icon(Icons.home, size: 32),
color: Colors.blue,
tooltip: '首页',
onPressed: () => _showMessage('首页'),
),
IconButton(
icon: const Icon(Icons.search, size: 32),
color: Colors.green,
tooltip: '搜索',
onPressed: () => _showMessage('搜索'),
),
IconButton(
icon: const Icon(Icons.add, size: 32),
color: Colors.orange,
tooltip: '添加',
onPressed: () => _showMessage('添加'),
),
IconButton(
icon: const Icon(Icons.delete, size: 32),
color: Colors.red,
tooltip: '删除',
onPressed: () => _showMessage('删除'),
),
],
),
]),
const Divider(height: 32),
_buildSection('五、列表项图标', [
const Text('在列表中使用图标:'),
const SizedBox(height: 12),
Card(
child: Column(
children: [
ListTile(
leading: const Icon(Icons.phone, color: Colors.green),
title: const Text('电话'),
subtitle: const Text('拨打电话'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () => _showMessage('电话'),
),
const Divider(height: 1),
ListTile(
leading: const Icon(Icons.email, color: Colors.blue),
title: const Text('邮件'),
subtitle: const Text('发送邮件'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () => _showMessage('邮件'),
),
const Divider(height: 1),
ListTile(
leading: const Icon(Icons.location_on, color: Colors.red),
title: const Text('位置'),
subtitle: const Text('查看位置'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16),
onTap: () => _showMessage('位置'),
),
],
),
),
]),
const Divider(height: 32),
_buildSection('六、空状态图标', [
const Text('使用大图标展示空状态:'),
const SizedBox(height: 12),
Container(
padding: const EdgeInsets.all(32),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Icon(
Icons.inbox,
size: 80,
color: Colors.grey[400],
),
const SizedBox(height: 16),
Text(
'暂无内容',
style: TextStyle(
fontSize: 18,
color: Colors.grey[600],
),
),
const SizedBox(height: 8),
Text(
'点击下方按钮添加新内容',
style: TextStyle(
fontSize: 14,
color: Colors.grey[500],
),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: () => _showMessage('添加内容'),
icon: const Icon(Icons.add),
label: const Text('添加'),
),
],
),
),
]),
],
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '首页',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: '搜索',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: '我的',
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () => _showMessage('浮动按钮'),
child: const Icon(Icons.add),
),
);
}
Widget _buildSection(String title, List<Widget> children) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
...children,
],
);
}
Widget _buildIconItem(IconData icon, String label) {
return Column(
children: [
Icon(icon, size: 32, color: Colors.blue),
const SizedBox(height: 4),
Text(label, style: const TextStyle(fontSize: 12)),
],
);
}
Widget _buildIconWithSize(IconData icon, double size, String label) {
return Column(
children: [
Icon(icon, size: size, color: Colors.blue),
const SizedBox(height: 4),
Text(label, style: const TextStyle(fontSize: 12)),
],
);
}
Widget _buildIconWithColor(IconData icon, Color color, String label) {
return Column(
children: [
Icon(icon, size: 32, color: color),
const SizedBox(height: 4),
Text(label, style: const TextStyle(fontSize: 12)),
],
);
}
void _showMessage(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('点击了: $message')),
);
}
}
代码说明:
- 基础图标:展示了最简单的 Icon 使用方式
- 不同尺寸:通过
size属性控制图标大小(16dp - 64dp) - 不同颜色:通过
color属性设置图标颜色 - IconButton:展示可点击的图标按钮及其 tooltip 提示
- 列表项图标:在 ListTile 中使用图标
- 空状态图标:使用大图标展示空状态页面
- 底部导航栏:在 BottomNavigationBar 中使用图标
- 浮动按钮:在 FloatingActionButton 中使用图标
十一、总结
Icon 组件是 Flutter 中最基础也是最重要的组件之一。通过本文的学习,我们掌握了:
- Icon 组件的基本概念:了解了图标在 UI 设计中的重要性
- Flutter 图标系统:认识了 Material Design、Cupertino 和自定义图标
- Icon 的基本用法:学会了创建、设置大小和颜色的图标
- Icon 的各种属性:掌握了 icon、size、color、semanticLabel 等属性
- IconButton 图标按钮:学会了创建可点击的图标按钮
- IconTheme 主题管理:了解了如何统一管理图标样式
- 常用图标分类:掌握了各类常用图标的速查方法
- 实际应用场景:学会了在导航栏、列表、空状态等场景中使用图标
💡 学习建议:图标是 UI 设计的基础元素,建议多浏览 Material Design 图标库,熟悉常用图标的名称和用途。在实际开发中,保持图标风格的一致性非常重要。
📚 延伸阅读:
更多推荐
所有评论(0)