Flutter + 开源鸿蒙实战|城市智慧停车管理系统 Day5 超时提醒弹窗+深浅色全局主题+登录页面+记住登录+隐私协议+全局UI美化+鸿蒙打包配置

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

<!-- Schema.org 结构化数据 -->
<script type="application/ld+json">
{
  "@context":"https://schema.org",
  "type":"BlogPosting",
  "headline":"Flutter+开源鸿蒙实战 城市智慧停车管理系统Day5 超时提醒+深浅色主题+登录页+记住登录+隐私弹窗+UI美化+鸿蒙打包",
  "author":{"type":"Person","name":"鸿蒙跨端开发者"},
  "publisher":{"type":"Organization","name":"开源鸿蒙技术社区"},
  "datePublished":"2026-05-09",
  "description":"商业级非校园实战项目Day5,实现停车超时计费提醒弹窗、全局深浅色一键切换主题、完整登录页面、记住登录本地缓存、首次启动隐私协议弹窗、全局UI精细化美化、鸿蒙打包签名配置,完成体验层与上架规范收尾,适配鸿蒙手机平板,毕设可直接真机演示",
  "keywords":"Flutter,开源鸿蒙,OpenHarmony,智慧停车,超时提醒,深浅主题,登录页面,隐私协议,UI美化,鸿蒙打包"
}
</script>

一、前言

哈喽小伙伴们,我们继续推进城市智慧停车管理系统实战开发,全程面向城市商圈、小区、市政停车场真实商用场景,无任何校园同质化内容,整套项目业务闭环完整、技术栈硬核、交互体验拉满。

快速复盘前4天完整开发进度:

  • Day1:项目初始化、企业级分层架构、高德地图/定位/权限/缓存等全套第三方库集成、GetX全局状态、底部导航与页面骨架;
  • Day2:高德地图全屏展示、实时定位、车场点位标注、搜索筛选、车场卡片、全局路由配置,完成地图查询底座;
  • Day3:车场详情页、车位预约、阶梯式停车计费、路线导航、停车实时计时,实现预约‑停车‑计费‑导航核心业务;
  • Day4:停车订单生成、多状态管理、在线缴费、我的订单、会员中心、个人中心与退出登录,完成订单与支付商业闭环。

来到 Day5,我们不再新增复杂业务逻辑,重点打磨用户体验、系统规范、全局视觉、登录体系、隐私合规、打包部署,把项目从“功能完整”升级为“商用级可交付产品”,也是毕设真机演示、作品集展示的关键优化环节。

本文严格沿用固定写作规范:口语化叙事、代码精简5–6行、步骤清晰、鸿蒙全端适配、文末配套4张实景配图,格式风格和前序完全统一。

今日Day5 核心开发任务(逐项落地)

  1. 开发停车超时自动提醒弹窗,超时后触发额外计费提示;
  2. 封装全局主题控制器,实现浅色/深色模式一键切换;
  3. 配置两套主题样式,全页面自动跟随切换;
  4. 搭建完整登录页面,账号密码登录+登录校验;
  5. 实现记住登录本地缓存,自动回填账号密码;
  6. 开发首次启动隐私协议弹窗,符合鸿蒙上架合规要求;
  7. 全局UI统一美化:按钮、输入框、卡片、间距、圆角标准化;
  8. 配置鸿蒙打包签名,生成hap安装包;
  9. 整理Day5高频问题与新手避坑方案。
    在这里插入图片描述

二、版块1:停车超时提醒弹窗开发

文字讲解

真实停车业务中,超时未缴费会产生滞纳金,我们实现自动判断时长,超时后弹出提醒弹窗,展示超时时长、额外费用、缴费入口,完善风控逻辑。

// 控制器超时判断方法
void checkOverTime(int parkHour) {
  if(parkHour > 24) {
    double extraFee = (parkHour - 24) * 2;
    showOverTimeDialog(extraFee);
  }
}
void showOverTimeDialog(double extraFee) {
  Get.dialog(AlertDialog(
    title: const Text("停车超时提醒"),
    content: Text("已停车超过24小时,超时额外费用:${extraFee.toStringAsFixed(2)}元"),
    actions: [
      TextButton(onPressed: ()=>Get.back(), child: const Text("稍后处理")),
      TextButton(onPressed: ()=>Get.toNamed(RoutePath.order), child: const Text("立即缴费"))
    ]
  ));
}

三、版块2:全局主题控制器封装

文字讲解

使用GetX做全局主题状态管理,一键切换深浅色模式,所有页面自动响应式刷新,不用逐个页面修改样式。

class ThemeController extends GetxController {
  static ThemeController get to => Get.find();
  final RxBool isDarkMode = false.obs;

  void toggleTheme() {
    isDarkMode.value = !isDarkMode.value;
  }
}

四、版块3:深浅两套全局主题配置

文字讲解

在main.dart根据主题控制器动态切换ThemeData,浅色采用商务蓝灰,深色采用暗夜灰黑,全局统一配色规范。

ThemeData getLightTheme() {
  return ThemeData(
    primarySwatch: Colors.blueGrey,
    scaffoldBackgroundColor: Colors.white,
  );
}

ThemeData getDarkTheme() {
  return ThemeData(
    primarySwatch: Colors.grey,
    scaffoldBackgroundColor: Color(0xFF121212),
  );
}

在这里插入图片描述

文字讲解

在GetMaterialApp中监听主题状态,实现全局动态切换。

GetMaterialApp(
  theme: ThemeController.to.isDarkMode.value ? getDarkTheme() : getLightTheme(),
)

五、版块4:个人中心添加主题切换开关

文字讲解

在个人中心页面增加Switch开关,绑定主题控制器,一键切换深浅模式,交互直观流畅。

Obx(()=>SwitchListTile(
  title: const Text("深色模式"),
  value: ThemeController.to.isDarkMode.value,
  onChanged: (val)=>ThemeController.to.toggleTheme(),
))

六、版块5:完整登录页面搭建

文字讲解

从零搭建简约商务风登录页面,包含logo、账号输入框、密码输入框、记住我复选框、登录按钮,键盘自动避让,适配鸿蒙小屏手机。

class LoginPage extends StatelessWidget {
  LoginPage({super.key});
  final TextEditingController userCtrl = TextEditingController();
  final TextEditingController pwdCtrl = TextEditingController();
  final RxBool rememberMe = false.obs;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: buildAppBar("用户登录"),
      body: Padding(
        padding: EdgeInsets.all(AppStyle.padding),
        child: Column(
          children: [
            buildInput(userCtrl, "请输入账号"),
            SizedBox(height:15.h),
            buildInput(pwdCtrl, "请输入密码", obscureText: true),
            Obx(()=>CheckboxListTile(
              title: const Text("记住登录"),
              value: rememberMe.value,
              onChanged: (v)=>rememberMe.value = v!,
            )),
            SizedBox(height:20.h),
            buildPrimaryBtn("立即登录", ()=>doLogin()),
          ],
        ),
      ),
    );
  }
}

七、版块6:记住登录本地缓存实现

文字讲解

勾选记住我后,将账号密码存入SharedPreferences,下次打开APP自动回填,优化用户登录体验。

Future<void> saveLoginInfo(String user,String pwd) async {
  final sp = await SharedPreferences.getInstance();
  await sp.setString("login_user", user);
  await sp.setString("login_pwd", pwd);
}

Future<void> getLoginInfo() async {
  final sp = await SharedPreferences.getInstance();
  userCtrl.text = sp.getString("login_user") ?? "";
  pwdCtrl.text = sp.getString("login_pwd") ?? "";
}

八、版块7:登录逻辑+权限校验

文字讲解

简单校验账号密码,登录成功存入全局AuthController,跳转首页;未登录用户禁止进入订单、会员页面,结合路由守卫实现权限拦截。

void doLogin() {
  if(userCtrl.text.isEmpty || pwdCtrl.text.isEmpty) {
    ToastUtil.show("账号密码不能为空");
    return;
  }
  authCtrl.login(UserModel(name:userCtrl.text,isVip:false));
  Get.offAllNamed(RoutePath.home);
}

在这里插入图片描述

九、版块8:首次启动隐私协议弹窗

文字讲解

符合鸿蒙应用上架规范,首次打开APP弹出隐私政策弹窗,同意后永久不再弹出,拒绝则退出应用。

Future<void> checkPrivacyAgree() async {
  final sp = await SharedPreferences.getInstance();
  bool agree = sp.getBool("privacy_agree") ?? false;
  if(!agree) {
    Get.dialog(privacyDialog());
  }
}
Widget privacyDialog() {
  return AlertDialog(
    title: const Text("用户隐私协议"),
    content: const Text("本应用将获取定位、网络权限,用于查询附近停车场、导航、停车计费。"),
    actions: [
      TextButton(onPressed: ()=>exit(0), child: const Text("拒绝")),
      TextButton(onPressed: ()async{
        final sp = await SharedPreferences.getInstance();
        await sp.setBool("privacy_agree",true);
        Get.back();
      }, child: const Text("同意"))
    ]
  );
}

十、版块9:全局UI精细化统一美化

文字讲解

统一全局样式:主色、圆角、阴影、间距、按钮水波纹、卡片样式、输入框样式,全部复用全局常量,全APP视觉风格一致,毕设观感大幅提升。

// 统一按钮水波纹
Widget buildPrimaryBtn(String text, VoidCallback onTap) {
  return ElevatedButton(
    onPressed: onTap,
    style: ElevatedButton.styleFrom(
      splashFactory: InkRipple.splashFactory,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(AppStyle.radius))
    ),
    child: Text(text,style: TextStyle(fontSize:15.sp)),
  );
}

十一、版块10:鸿蒙打包签名配置

文字讲解

配置鸿蒙签名文件,生成hap可安装包,真机直接运行演示,适配鸿蒙4.0+系统,满足毕设真机答辩需求。

# ohos/module.json5 签名配置
"signingConfig": {
  "path": "./signature/debug.p12",
  "keyAlias": "debug",
  "storePassword": "123456"
}

在这里插入图片描述

十二、版块11:Day5 新手高频问题详解

问题1:深浅色切换部分页面不生效?

解答:页面必须用Obx包裹;主题变量统一用ThemeController;自定义颜色不要写死硬编码。

问题2:记住登录重启后数据丢失?

解答:保存key名称必须一致;异步方法必须加await;不要在同步生命周期直接读取。

问题3:隐私弹窗每次打开都弹出?

解答:同意后必须写入本地缓存;初始化时异步读取;不要同步直接判断布尔值。

问题4:登录页面键盘遮挡输入框?

解答:页面外层包裹SingleChildScrollView;全部使用.w/.h适配单位。

问题5:鸿蒙打包签名失败?

解答:签名路径不能含中文;包名、别名、密码一一对应;SDK版本匹配。

十三、Day5 开发总结

今天Day5我们完成体验层+合规层+部署层全维度优化,项目正式达到商用级交付标准:

  1. 实现停车超时提醒弹窗,完善超时计费风控逻辑;
  2. 封装全局主题控制器,完成深浅色模式一键切换;
  3. 搭建完整登录页面,实现记住登录、本地缓存;
  4. 开发隐私协议弹窗,满足鸿蒙上架合规要求;
  5. 全局UI精细化统一美化,视觉专业度大幅提升;
  6. 配置鸿蒙打包签名,支持真机直接安装演示;
  7. 完善登录权限校验,结合路由守卫实现权限闭环;
  8. 汇总高频问题,提供落地解决方案。

至此,智慧停车系统已具备:地图定位‑车场查询‑车位预约‑计时停车‑阶梯计费‑导航‑订单缴费‑会员体系‑登录权限‑主题切换‑隐私合规‑真机部署全链路能力,完全对标真实商用停车APP,毕设、面试项目极具竞争力。

十四、下期Day6预告

Day6将进行:全局通用组件深度封装、意见反馈+系统设置页面开发、清除缓存功能、代码整体重构优化、修复全部遗留bug、最终项目细节调优。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐