Flutter for OpenHarmony垃圾分类指南App实战:政策法规实现

垃圾分类不是随便分分就行的,背后是有法律法规支撑的。政策法规页面就是让用户了解这些规定,知道垃圾分类是有法可依的,不是可做可不做的事情。

为什么需要这个页面

很多人可能觉得垃圾分类只是一种倡导,做不做无所谓。但实际上,从2017年开始,国家就出台了一系列政策法规来推动垃圾分类工作。了解这些政策有几个好处:

  1. 提高重视程度:知道这是法律要求,不是可选项
  2. 了解处罚标准:知道违规的后果
  3. 理解政策背景:知道为什么要这样分类

这个页面的目标是用简洁的方式呈现这些信息,让用户快速了解政策概况,而不是把整个法规文本都堆上去。

数据结构设计

政策法规的数据包含标题、实施时间和内容摘要:

dart 复制代码
class PolicyPage extends StatelessWidget {
  const PolicyPage({super.key});

  @override
  Widget build(BuildContext context) {
    // 政策法规数据
    // 实际项目中这些数据可能来自后端接口
    final policies = [
      {
        'title': '《生活垃圾分类制度实施方案》',
        'date': '2017年3月',
        'summary': '国务院办公厅发布,要求在全国46个重点城市先行实施生活垃圾强制分类。',
        'level': '国家级',
      },
      {
        'title': '《上海市生活垃圾管理条例》',
        'date': '2019年7月',
        'summary': '上海率先实施垃圾分类,将生活垃圾分为可回收物、有害垃圾、湿垃圾、干垃圾四类。',
        'level': '地方级',
      },

这些都是真实的政策法规,时间线从2017年到2020年,展示了垃圾分类政策的推进过程。

继续看后面的数据:

dart 复制代码
      {
        'title': '《北京市生活垃圾管理条例》',
        'date': '2020年5月',
        'summary': '北京实施垃圾分类,将生活垃圾分为厨余垃圾、可回收物、有害垃圾、其他垃圾四类。',
        'level': '地方级',
      },
      {
        'title': '《固体废物污染环境防治法》',
        'date': '2020年9月',
        'summary': '新修订的固废法明确了生活垃圾分类制度,推动垃圾分类工作法治化。',
        'level': '国家级',
      },
      {
        'title': '《"十四五"城镇生活垃圾分类和处理设施发展规划》',
        'date': '2021年5月',
        'summary': '明确到2025年底,全国城市生活垃圾分类收运能力达到70万吨/日以上。',
        'level': '国家级',
      },
      {
        'title': '《关于进一步推进生活垃圾分类工作的若干意见》',
        'date': '2020年11月',
        'summary': '住建部等12部门联合发布,要求到2025年基本建立配套完善的生活垃圾分类法规制度体系。',
        'level': '国家级',
      },
    ];

内容选择:选了几个有代表性的政策,包括国家层面的方案、地方性法规、以及专门的法律。让用户对政策体系有个整体认识。数据按时间顺序排列,用户可以看到政策是怎么一步步推进的。

页面布局

页面结构包含一个说明区域和政策列表:

dart 复制代码
    return Scaffold(
      appBar: AppBar(title: const Text('政策法规')),
      body: Column(
        children: [
          // 顶部说明区域
          _buildHeader(),
          // 政策列表
          Expanded(
            child: ListView.builder(
              padding: EdgeInsets.all(16.w),
              itemCount: policies.length,
              itemBuilder: (context, index) {
                final policy = policies[index];
                return _buildPolicyCard(policy);
              },
            ),
          ),
        ],
      ),
    );
  }

ListView.builder渲染政策列表,这样即使政策数量很多,也能保持良好的性能。

顶部说明区域

在列表上方加一个说明区域,告诉用户这个页面是干什么的:

dart 复制代码
Widget _buildHeader() {
  return Container(
    margin: EdgeInsets.all(16.w),
    padding: EdgeInsets.all(16.w),
    decoration: BoxDecoration(
      // 使用浅蓝色背景,表示"信息"
      color: Colors.blue.withOpacity(0.1),
      borderRadius: BorderRadius.circular(12.r),
      border: Border.all(color: Colors.blue.withOpacity(0.3)),
    ),
    child: Row(
      children: [
        Icon(Icons.info_outline, color: Colors.blue, size: 24.sp),
        SizedBox(width: 12.w),
        Expanded(
          child: Text(
            '垃圾分类已纳入法律法规体系,了解相关政策有助于更好地参与垃圾分类工作。',
            style: TextStyle(fontSize: 14.sp, color: Colors.blue.shade700),
          ),
        ),
      ],
    ),
  );
}

这个说明区域用蓝色调,表示这是"信息提示"而不是"警告"。文案简洁明了,告诉用户为什么要了解这些政策。

政策卡片组件

每张卡片包含图标、标题、时间、级别标签和摘要:

dart 复制代码
Widget _buildPolicyCard(Map<String, String> policy) {
  // 根据政策级别确定标签颜色
  final isNational = policy['level'] == '国家级';
  final levelColor = isNational ? Colors.red : Colors.orange;
  
  return Card(
    margin: EdgeInsets.only(bottom: 12.h),
    // 添加轻微阴影
    elevation: 2,
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(12.r),
    ),

Card组件包裹每条政策,自带阴影和圆角,看起来比较有层次感。

卡片内容结构:

dart 复制代码
    child: Padding(
      padding: EdgeInsets.all(16.w),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 第一行:图标、标题、级别标签
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 政策图标
              Container(
                width: 40.w,
                height: 40.w,
                decoration: BoxDecoration(
                  color: AppTheme.primaryColor.withOpacity(0.1),
                  borderRadius: BorderRadius.circular(8.r),
                ),
                child: Icon(
                  Icons.policy,
                  color: AppTheme.primaryColor,
                  size: 24.sp,
                ),
              ),
              SizedBox(width: 12.w),
              // 标题和级别标签
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    // 标题
                    Text(
                      policy['title']!,
                      style: TextStyle(
                        fontSize: 15.sp,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    SizedBox(height: 4.h),
                    // 级别标签和时间
                    Row(
                      children: [
                        // 级别标签
                        Container(
                          padding: EdgeInsets.symmetric(
                            horizontal: 6.w,
                            vertical: 2.h,
                          ),
                          decoration: BoxDecoration(
                            color: levelColor.withOpacity(0.1),
                            borderRadius: BorderRadius.circular(4.r),
                          ),
                          child: Text(
                            policy['level']!,
                            style: TextStyle(
                              fontSize: 10.sp,
                              color: levelColor,
                              fontWeight: FontWeight.w500,
                            ),
                          ),
                        ),
                        SizedBox(width: 8.w),
                        // 实施时间
                        Text(
                          '实施时间:${policy['date']}',
                          style: TextStyle(
                            fontSize: 12.sp,
                            color: Colors.grey,
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ],
          ),

标题前面放了个政策图标,让用户一眼就知道这是官方文件。Expanded包裹标题文字,这样标题太长时会自动换行而不是溢出。

级别标签用不同颜色区分:

  • 国家级:红色,表示最高级别
  • 地方级:橙色,表示地方性法规

接下来是摘要:

dart 复制代码
          SizedBox(height: 12.h),
          // 分隔线
          Divider(height: 1, color: Colors.grey.shade200),
          SizedBox(height: 12.h),
          // 摘要内容
          Text(
            policy['summary']!,
            style: TextStyle(
              fontSize: 14.sp,
              height: 1.6,
              color: Colors.grey.shade700,
            ),
          ),
          SizedBox(height: 8.h),
          // 查看详情按钮
          Align(
            alignment: Alignment.centerRight,
            child: TextButton(
              onPressed: () => _showPolicyDetail(policy),
              child: Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text(
                    '查看详情',
                    style: TextStyle(
                      fontSize: 13.sp,
                      color: AppTheme.primaryColor,
                    ),
                  ),
                  Icon(
                    Icons.arrow_forward,
                    size: 14.sp,
                    color: AppTheme.primaryColor,
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    ),
  );
}

摘要用灰色文字显示,行高1.6保证可读性。底部有个"查看详情"按钮,点击可以查看完整的法规内容。

查看详情功能

点击"查看详情"可以弹出一个对话框或跳转到详情页:

dart 复制代码
void _showPolicyDetail(Map<String, String> policy) {
  Get.dialog(
    AlertDialog(
      title: Text(
        policy['title']!,
        style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.bold),
      ),
      content: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: [
            // 基本信息
            _buildDetailItem('实施时间', policy['date']!),
            _buildDetailItem('政策级别', policy['level']!),
            SizedBox(height: 12.h),
            // 摘要
            Text(
              '政策摘要',
              style: TextStyle(
                fontSize: 14.sp,
                fontWeight: FontWeight.bold,
              ),
            ),
            SizedBox(height: 8.h),
            Text(
              policy['summary']!,
              style: TextStyle(fontSize: 14.sp, height: 1.6),
            ),
            SizedBox(height: 16.h),
            // 提示
            Container(
              padding: EdgeInsets.all(12.w),
              decoration: BoxDecoration(
                color: Colors.grey.shade100,
                borderRadius: BorderRadius.circular(8.r),
              ),
              child: Text(
                '如需查看完整法规文本,请访问国家或地方政府官方网站。',
                style: TextStyle(
                  fontSize: 12.sp,
                  color: Colors.grey.shade600,
                ),
              ),
            ),
          ],
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Get.back(),
          child: const Text('关闭'),
        ),
      ],
    ),
  );
}

Widget _buildDetailItem(String label, String value) {
  return Padding(
    padding: EdgeInsets.only(bottom: 8.h),
    child: Row(
      children: [
        Text(
          '$label:',
          style: TextStyle(
            fontSize: 14.sp,
            color: Colors.grey,
          ),
        ),
        Text(
          value,
          style: TextStyle(fontSize: 14.sp),
        ),
      ],
    ),
  );
}

设计考量

1. 信息密度适中

每条政策只展示最核心的信息:是什么、什么时候实施、主要内容是什么。不需要把整个法规文本都放进来,那样用户根本不会看。

2. 时间线呈现

数据按时间顺序排列,用户可以看到政策是怎么一步步推进的。从2017年的方案到2020年的法律,垃圾分类从倡导变成了强制。

3. 权威感

用了Icons.policy这个图标,加上书名号包裹的标题,整体给人一种正式、权威的感觉。这和页面的内容性质是匹配的。

4. 层级区分

用颜色标签区分国家级和地方级政策,让用户快速了解政策的层级。

可以扩展的方向

如果要做得更完善,可以考虑:

1. 点击查看详情

跳转到详情页展示完整的法规内容,或者链接到官方网站。

dart 复制代码
void _openPolicyUrl(String url) {
  launchUrl(Uri.parse(url));
}

2. 按地区筛选

用户可以只看自己所在城市的政策:

dart 复制代码
Widget _buildFilterChips() {
  return Wrap(
    spacing: 8.w,
    children: ['全部', '国家级', '上海', '北京', '广州'].map((filter) {
      return FilterChip(
        label: Text(filter),
        selected: _selectedFilter == filter,
        onSelected: (selected) {
          setState(() => _selectedFilter = filter);
        },
      );
    }).toList(),
  );
}

3. 更新提醒

有新政策出台时推送通知:

dart 复制代码
void checkPolicyUpdates() async {
  final newPolicies = await api.getNewPolicies();
  if (newPolicies.isNotEmpty) {
    showNotification('有${newPolicies.length}条新政策发布');
  }
}

4. 收藏功能

用户可以收藏关心的政策:

dart 复制代码
Widget _buildBookmarkButton(String policyId) {
  return Obx(() => IconButton(
    icon: Icon(
      controller.isBookmarked(policyId)
          ? Icons.bookmark
          : Icons.bookmark_border,
    ),
    onPressed: () => controller.toggleBookmark(policyId),
  ));
}

5. 搜索功能

政策多了之后,可以加个搜索框:

dart 复制代码
Widget _buildSearchBar() {
  return TextField(
    onChanged: (value) {
      setState(() {
        _filteredPolicies = policies.where((p) =>
          p['title']!.contains(value) ||
          p['summary']!.contains(value)
        ).toList();
      });
    },
    decoration: InputDecoration(
      hintText: '搜索政策法规',
      prefixIcon: Icon(Icons.search),
    ),
  );
}

数据来源说明

实际项目中,政策数据应该从可靠的来源获取:

  1. 政府官方网站:最权威的来源
  2. 后端接口:由运营人员维护,定期更新
  3. 本地数据库:首次加载后缓存到本地
dart 复制代码
class PolicyRepository {
  // 从后端获取政策列表
  Future<List<Policy>> fetchPolicies() async {
    try {
      final response = await dio.get('/api/policies');
      return (response.data as List)
          .map((json) => Policy.fromJson(json))
          .toList();
    } catch (e) {
      // 网络错误时返回本地缓存
      return _getLocalPolicies();
    }
  }
  
  // 获取本地缓存的政策
  List<Policy> _getLocalPolicies() {
    final data = storage.read('policies');
    if (data != null) {
      return (data as List)
          .map((json) => Policy.fromJson(json))
          .toList();
    }
    return [];
  }
}

这个页面的实现比较简单,但内容很重要。让用户知道垃圾分类是有法律依据的,能提高他们的重视程度。


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

相关推荐
春日见3 小时前
Autoware使用教程
大数据·人工智能·深度学习·elasticsearch·搜索引擎·docker·容器
一起养小猫3 小时前
Flutter for OpenHarmony 实战:从零开发一款五子棋游戏
android·前端·javascript·flutter·游戏·harmonyos
一起养小猫3 小时前
Flutter for OpenHarmony 实战:天气预报应用UI设计与主题切换
jvm·数据库·spring·flutter·ui·harmonyos
新缸中之脑3 小时前
在OpenClaw中构建专业AI角色
大数据·人工智能
晚霞的不甘3 小时前
Flutter for OpenHarmony全面升级「今日运势」 应用的视觉与交互革新
前端·学习·flutter·前端框架·交互
向哆哆3 小时前
高校四六级报名系统通知公告模块实战:基于 Flutter × OpenHarmony 跨端开发
flutter·开源·鸿蒙·openharmony·开源鸿蒙
Gain_chance3 小时前
27-学习笔记尚硅谷数仓搭建-数据仓库DWD层介绍及其事务表(行为)相关概念
大数据·数据仓库·笔记·学习
EveryPossible4 小时前
大数据模型练习1
大数据
晚霞的不甘4 小时前
Flutter for OpenHarmony智能穿搭推荐:构建一个实用又美观的个性化衣橱助手
前端·经验分享·flutter·ui·前端框架