🔥 Flutter + 开源鸿蒙实战 | 极简记账本 Day1:项目初始化 + 底部导航框架搭建

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

系列项目:极简记账本(6 天完结)

难度:新手友好・可直接运行

📌 本文导读(必看)

本文是极简记账本系列第一篇,目标:

  • ✅ 新建 Flutter 干净项目
  • ✅ 配置依赖(shared_preferences)
  • ✅ 搭建4 Tab 底部导航(首页 / 记账 / 统计 / 我的)
  • ✅ 鸿蒙风格基础布局,可直接运行
  • ✅ 全程无冗余代码,适合系列迭代

适合人群:Flutter 初学者、需要快速完成项目的学生、想练手跨平台 + 鸿蒙适配的开发者。

🧱 一、创建项目 & 目录说明

1.1 创建项目

打开终端执行:

flutter create ledger_app
cd ledger_app

1.2 项目目录(精简版)

ledger_app/
├── lib/
│   └── main.dart       # 入口 + 底部导航
├── pubspec.yaml        # 依赖配置

⚙️ 二、配置 pubspec.yaml(完整可直接复制)

name: ledger_app
description: 极简记账本 - Flutter+鸿蒙实战项目
version: 1.0.0+1

environment:
  sdk: '>=3.0.0 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.3

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0

flutter:
  uses-material-design: true

保存后执行:

flutter pub get

🚀 三、main.dart 完整代码(可直接运行)

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '极简记账本',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.teal,
        useMaterial3: true,
      ),
      home: const MainBottomPage(),
    );
  }
}

// 底部导航主页面
class MainBottomPage extends StatefulWidget {
  const MainBottomPage({super.key});

  @override
  State<MainBottomPage> createState() => _MainBottomPageState();
}

class _MainBottomPageState extends State<MainBottomPage> {
  int _currentIndex = 0;

  // 四个子页面
  final List<Widget> _pageList = const [
    HomePage(),
    AddBillPage(),
    StatisticPage(),
    MinePage(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _pageList[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        type: BottomNavigationBarType.fixed,
        selectedItemColor: Colors.teal,
        unselectedItemColor: Colors.grey,
        onTap: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.home_outlined),
            label: '首页',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.add_circle_outline),
            label: '记账',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.bar_chart_outlined),
            label: '统计',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person_outlined),
            label: '我的',
          ),
        ],
      ),
    );
  }
}

// 首页
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('首页')),
      body: const Center(child: Text('首页页面 - 待开发')),
    );
  }
}

// 记账页面
class AddBillPage extends StatelessWidget {
  const AddBillPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('新增记账')),
      body: const Center(child: Text('记账页面 - 待开发')),
    );
  }
}

// 统计页面
class StatisticPage extends StatelessWidget {
  const StatisticPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('收支统计')),
      body: const Center(child: Text('统计页面 - 待开发')),
    );
  }
}

// 我的页面
class MinePage extends StatelessWidget {
  const MinePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('个人中心')),
      body: const Center(child: Text('我的页面 - 待开发')),
    );
  }
}

🔍四、重点代码逐行解析

1. 底部导航核心逻辑

int _currentIndex = 0;
final List<Widget> _pages = const [
  HomePage(),
  AddBillPage(),
  StatisticPage(),
  MinePage(),
];
  • _currentIndex:记录当前选中的导航下标,默认 0,默认打开首页
  • _pages:按顺序存放四个子页面,和底部导航选项一一对应
  • 后续切换下标,就能自动切换展示对应页面,是 Flutter 底部导航最经典写法。

2. 页面主体联动逻辑

body: _pages[_currentIndex],
  • 根据当前下标 _currentIndex,从页面列表取出对应页面渲染;
  • 不用手动跳转路由,只改下标就能实现无缝页面切换,代码简洁易维护。

3. BottomNavigationBar 基础配置

type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.teal,
unselectedItemColor: Colors.grey,
  • fixed:多个导航选项时图标文字不会自动缩放变形,固定布局更美观;
  • selectedItemColor:选中导航项的主题色调;
  • unselectedItemColor:未选中导航项置灰显示,区分状态。

4. 导航点击切换事件

onTap: (index) => setState(() => _currentIndex = index),
  • 点击底部任意导航项,会带回当前点击的下标 index
  • setState() 刷新状态,更新 _currentIndex,页面立刻自动刷新切换;
  • 整行箭头函数简写,代码更优雅,适合项目规范写法。

5. 导航条目定义

BottomNavigationBarItem(
  icon: Icon(Icons.home_outlined), 
  label: '首页'
)
  • icon:设置导航图标,采用系统轮廓图标,风格简约适配鸿蒙 / 安卓 /iOS;
  • label:导航下方文字说明;
  • 四个条目顺序必须和 _pages 页面列表严格对应,否则页面会错乱。

6. 全局主题与适配

theme: ThemeData(
  primarySwatch: Colors.teal,
  useMaterial3: true,
)
  • primarySwatch:设置项目全局主色调,AppBar、按钮、主题色统一复用;
  • useMaterial3:启用 Material3 全新设计风格,兼容新版 Flutter 和开源鸿蒙 UI 规范。

📸 五、运行效果(配图占位,你截图后替换即可)

  • 启动后默认进入首页
  • 底部 4 个 Tab 可正常点击切换
  • 整体风格简约,适配鸿蒙 / 安卓 /iOS
  • 无报错、无警告,热重载正常

✅ 六、Day1 完成总结

今天完成:

  1. ✅ 创建独立项目 ledger_app
  2. ✅ 配置依赖(shared_preferences)
  3. ✅ 搭建 4 Tab 底部导航框架
  4. ✅ 四个页面骨架完成,可切换
  5. ✅ 代码干净、无冗余、可直接运行

明日预告(Day2):

  • 记账页完善:收支选择器、金额输入、分类选择
  • 本地存储:用 shared_preferences 保存账单
  • 添加账单功能:点击保存即可写入本地

📚 七、系列推荐(后续文章)

  • Day2:记账页面 + 本地存储(已更新)
  • Day3:首页账单列表 + 当月收支统计
  • Day4:统计页饼图 + 日期筛选
  • Day5:个人中心 + 数据重置
  • Day6:优化 + 鸿蒙适配 + 项目总结
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐