You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 17:01:12