如何在Flutter中创建类似iOS通知中心的列表UI
在Flutter中实现iOS通知中心风格的列表UI
核心特征梳理
iOS通知中心的列表具备这些关键样式与交互特点:
- 按日期分组展示,顶部配有浅灰色背景的日期分隔栏
- 同组通知包裹在带圆角、柔和阴影的白色卡片容器内
- 单条通知采用「左侧图标+中间标题/内容+右侧时间」的横向布局
- 支持左滑触发删除/操作(可选)
- 整体背景为浅灰色,与白色卡片形成层次对比
实现代码与步骤
1. 定义数据模型
先创建一个通知数据类,封装所需字段:
class NotificationItem { final String date; final String icon; final String title; final String content; final String time; NotificationItem({ required this.date, required this.icon, required this.title, required this.content, required this.time, }); }
2. 构建日期分隔组件
自定义适配iOS风格的日期标题栏:
Widget _buildDateSeparator(String date) { return Container( width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), color: const Color(0xFFF2F2F7), child: Text( date, style: const TextStyle( fontSize: 13, color: Color(0xFF8E8E93), fontWeight: FontWeight.w500, ), ), ); }
3. 实现单条通知布局
完成通知项的横向结构,包含图标、内容区和时间:
Widget _buildNotificationItem(NotificationItem item) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 左侧图标容器 Container( width: 40, height: 40, decoration: BoxDecoration( color: const Color(0xFFE5E5EA), borderRadius: BorderRadius.circular(8), ), child: Center( child: Text(item.icon, style: const TextStyle(fontSize: 18)), ), ), const SizedBox(width: 12), // 中间标题与内容区 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( item.title, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w500, color: Colors.black, ), ), const SizedBox(height: 4), Text( item.content, style: const TextStyle( fontSize: 14, color: Color(0xFF8E8E93), ), maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), ), // 右侧时间文本 Text( item.time, style: const TextStyle( fontSize: 12, color: Color(0xFF8E8E93), ), ), ], ), ); }
4. 构建分组通知卡片
将同日期的通知包裹在带圆角和阴影的卡片中:
Widget _buildNotificationGroup(List<NotificationItem> group) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Column( children: group.map((item) => _buildNotificationItem(item)).toList(), ), ); }
5. 整合完整列表页面
使用ListView组合所有组件,同时实现简单的分组逻辑:
class iOSNotificationCenter extends StatelessWidget { // 模拟通知数据源 final List<NotificationItem> notifications = [ NotificationItem( date: "今天", icon: "📧", title: "邮件提醒", content: "您有一封新的工作邮件,请及时查看", time: "14:30", ), NotificationItem( date: "今天", icon: "📱", title: "系统更新", content: "iOS 17.1.2 已准备好安装,点击下载", time: "09:15", ), NotificationItem( date: "昨天", icon: "📅", title: "日历提醒", content: "明天下午2点有团队会议,请提前准备", time: "20:45", ), ]; // 按日期分组的工具方法 Map<String, List<NotificationItem>> _groupNotifications() { Map<String, List<NotificationItem>> groups = {}; for (var item in notifications) { groups.putIfAbsent(item.date, () => []).add(item); } return groups; } @override Widget build(BuildContext context) { final groupedNotifications = _groupNotifications(); return Scaffold( backgroundColor: const Color(0xFFF2F2F7), body: ListView( children: [ const SafeArea(child: SizedBox(height: 8)), // 遍历分组构建UI for (var entry in groupedNotifications.entries) Column( children: [ _buildDateSeparator(entry.key), _buildNotificationGroup(entry.value), ], ), ], ), ); } }
6. 添加左滑操作(可选)
如果需要iOS风格的左滑删除功能,用Dismissible包裹单条通知项:
Widget _buildNotificationItem(NotificationItem item) { return Dismissible( key: Key(item.title), direction: DismissDirection.endToStart, background: Container( alignment: Alignment.centerRight, padding: const EdgeInsets.only(right: 16), color: Colors.red, child: const Icon(Icons.delete, color: Colors.white), ), onDismissed: (direction) { // 这里添加删除通知的业务逻辑 }, child: Padding( // 原有的通知项布局代码 ), ); }
样式优化建议
- 微调卡片阴影的
blurRadius和offset参数,让阴影更贴近iOS的柔和质感 - 可根据需求调整文字颜色、字号,匹配系统字体风格
- 用
GestureDetector包裹通知项,添加点击跳转逻辑
内容的提问来源于stack exchange,提问作者Navjot Kumar
相关产品推荐
相关产品推荐

