🛡️ 鸿蒙+Flutter 跨平台开发——密码管理APP的实现

🚀运行效果展示

在这里插入图片描述

在这里插入图片描述

📖 前言

在数字化时代,密码已成为我们生活中不可或缺的一部分。从社交媒体到银行账户,从购物平台到办公系统,我们每天都需要处理大量的密码。然而,如何安全、高效地管理这些密码,成为了许多人的难题。

📱 应用介绍

功能概述

我们开发的密码管理APP具有以下核心功能:

功能模块 主要特性 图标
📋 密码列表 展示所有密码,支持搜索和分类筛选 🔍
➕ 添加密码 支持手动添加和自动生成密码
🔒 密码详情 查看、编辑、复制密码信息 👁️
🔄 密码生成 生成高强度随机密码 🔄
🔖 分类管理 支持自定义密码分类 🏷️
🔍 搜索功能 支持按标题、用户名、网址搜索 🔎

技术栈

技术/框架 版本 用途
Flutter 3.x 跨平台UI框架
Provider 6.1.2 状态管理
SharedPreferences 2.5.3 本地数据存储
random_string 2.3.1 密码生成
Material Design 3 - UI设计规范

🏗️ 核心功能实现

1. 项目结构设计

lib/
├── main.dart              # 应用入口,底部导航实现
├── models/
│   └── password_item.dart # 密码数据模型
├── services/
│   └── storage_service.dart # 存储服务
└── screens/
    ├── password_list_screen.dart   # 密码列表
    ├── add_password_screen.dart    # 添加/编辑密码
    └── password_detail_screen.dart # 密码详情

2. 数据模型设计

密码数据模型是整个应用的基础,我们设计了PasswordItem类来表示密码条目:

/// 密码项数据模型
class PasswordItem {
  /// 唯一标识符
  final String id;
  
  /// 标题(如:微信、支付宝)
  String title;
  
  /// 用户名/邮箱
  String username;
  
  /// 密码
  String password;
  
  /// 网址
  String url;
  
  /// 备注
  String notes;
  
  /// 分类
  String category;
  
  /// 创建时间
  DateTime createdAt;
  
  /// 更新时间
  DateTime updatedAt;
  
  /// 构造函数
  PasswordItem({
    required this.id,
    required this.title,
    required this.username,
    required this.password,
    required this.url,
    required this.notes,
    required this.category,
    required this.createdAt,
    required this.updatedAt,
  });
  
  /// 从Map转换为PasswordItem(用于从存储中读取)
  factory PasswordItem.fromMap(Map<String, dynamic> map) {
    return PasswordItem(
      id: map['id'],
      title: map['title'],
      username: map['username'],
      password: map['password'],
      url: map['url'],
      notes: map['notes'],
      category: map['category'],
      createdAt: DateTime.parse(map['createdAt']),
      updatedAt: DateTime.parse(map['updatedAt']),
    );
  }
  
  /// 转换为Map(用于存储到本地)
  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'title': title,
      'username': username,
      'password': password,
      'url': url,
      'notes': notes,
      'category': category,
      'createdAt': createdAt.toIso8601String(),
      'updatedAt': updatedAt.toIso8601String(),
    };
  }
  
  /// 创建新密码项的工厂方法
  factory PasswordItem.newItem({
    required String title,
    required String username,
    required String password,
    String url = '',
    String notes = '',
    String category = '默认',
  }) {
    final now = DateTime.now();
    return PasswordItem(
      id: '${now.millisecondsSinceEpoch}',
      title: title,
      username: username,
      password: password,
      url: url,
      notes: notes,
      category: category,
      createdAt: now,
      updatedAt: now,
    );
  }
}

3. 状态管理设计

我们使用Provider进行状态管理,设计了PasswordProvider类来管理应用的所有状态:

/// 密码提供者,用于管理应用状态
class PasswordProvider with ChangeNotifier {
  final StorageService _storageService = StorageService();
  List<PasswordItem> _passwords = [];
  String _searchQuery = '';
  String _selectedCategory = '全部';
  bool _isLoading = false;

  /// 获取过滤后的密码列表
  List<PasswordItem> get passwords {
    // 搜索和分类过滤逻辑
    // ...
  }

  /// 加载所有密码
  Future<void> loadPasswords() async {
    _isLoading = true;
    notifyListeners();

    try {
      _passwords = await _storageService.getPasswords();
      // 按更新时间排序
      _passwords.sort((a, b) => b.updatedAt.compareTo(a.updatedAt));
    } catch (e) {
      debugPrint('加载密码失败: $e');
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 添加密码
  Future<void> addPassword(PasswordItem password) async {
    try {
      await _storageService.addPassword(password);
      await loadPasswords();
    } catch (e) {
      debugPrint('添加密码失败: $e');
      rethrow;
    }
  }

  /// 更新密码
  Future<void> updatePassword(PasswordItem password) async {
    // ...
  }

  /// 删除密码
  Future<void> deletePassword(String id) async {
    // ...
  }

  /// 设置搜索查询
  void setSearchQuery(String query) {
    _searchQuery = query;
    notifyListeners();
  }

  /// 设置选中的分类
  void setSelectedCategory(String category) {
    _selectedCategory = category;
    notifyListeners();
  }
}
状态管理流程图

用户操作

UI组件

PasswordProvider

StorageService

SharedPreferences

4. 存储服务实现

我们使用SharedPreferences实现本地数据存储,设计了StorageService类来封装存储操作:

/// 存储服务类,用于管理密码项的存储和检索
class StorageService {
  /// 存储键
  static const String _passwordsKey = 'passwords';
  
  /// 保存所有密码项
  Future<void> savePasswords(List<PasswordItem> passwords) async {
    final prefs = await SharedPreferences.getInstance();
    final List<Map<String, dynamic>> passwordMaps = passwords.map((item) => item.toMap()).toList();
    final String jsonString = jsonEncode(passwordMaps);
    await prefs.setString(_passwordsKey, jsonString);
  }
  
  /// 获取所有密码项
  Future<List<PasswordItem>> getPasswords() async {
    final prefs = await SharedPreferences.getInstance();
    final String? jsonString = prefs.getString(_passwordsKey);
    if (jsonString == null) {
      return [];
    }
    final List<dynamic> passwordMaps = jsonDecode(jsonString);
    return passwordMaps.map((map) => PasswordItem.fromMap(map)).toList();
  }
  
  /// 添加一个密码项
  Future<void> addPassword(PasswordItem password) async {
    final passwords = await getPasswords();
    passwords.add(password);
    await savePasswords(passwords);
  }
  
  /// 更新一个密码项
  Future<void> updatePassword(PasswordItem password) async {
    // ...
  }
  
  /// 删除一个密码项
  Future<void> deletePassword(String id) async {
    // ...
  }
}

5. UI界面实现

5.1 底部导航设计

应用采用底部导航栏实现拼豆生成器和密码管理器的切换:

/// 首页,包含底部导航栏
class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;

  // 导航项
  final List<Widget> _pages = [
    const PixelArtHomePage(),
    const PasswordListScreen(),
  ];

  // 导航标题
  final List<String> _appBarTitles = [
    '拼豆生成器',
    '密码管理',
  ];

  /// 切换底部导航
  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_appBarTitles[_selectedIndex]),
        centerTitle: true,
      ),
      body: _pages[_selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.image),
            label: '拼豆生成器',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.lock),
            label: '密码管理',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Theme.of(context).colorScheme.primary,
        onTap: _onItemTapped,
      ),
    );
  }
}
5.2 密码列表界面

密码列表支持搜索、分类筛选和滑动删除:

/// 密码列表屏幕
class PasswordListScreen extends StatefulWidget {
  // ...
}

class _PasswordListScreenState extends State<PasswordListScreen> {
  // ...

  
  Widget build(BuildContext context) {
    final provider = Provider.of<PasswordProvider>(context);
    final passwords = provider.passwords;

    return Scaffold(
      appBar: AppBar(
        title: _isSearching
            ? TextField(/* 搜索框 */)
            : const Text('密码管理器'),
        actions: [/* 搜索和筛选按钮 */],
      ),
      body: provider.isLoading
          ? const Center(child: CircularProgressIndicator())
          : passwords.isEmpty
              ? /* 空状态提示 */
              : ListView.builder(
                  itemCount: passwords.length,
                  itemBuilder: (context, index) {
                    final password = passwords[index];
                    return Dismissible(
                      key: Key(password.id),
                      direction: DismissDirection.endToStart,
                      background: /* 删除背景 */,
                      onDismissed: (direction) {
                        // 处理删除逻辑
                      },
                      child: ListTile(
                        leading: /* 图标 */,
                        title: Text(password.title),
                        subtitle: Text(password.username),
                        trailing: const Icon(Icons.arrow_forward_ios),
                        onTap: () {
                          // 跳转到密码详情页
                          Navigator.pushNamed(
                            context,
                            '/password_detail',
                            arguments: password,
                          );
                        },
                      ),
                    );
                  },
                ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.pushNamed(context, '/add_password');
        },
        tooltip: '添加密码',
        child: const Icon(Icons.add),
      ),
    );
  }
}
5.3 添加/编辑密码界面

支持手动输入和自动生成密码,包含表单验证:

/// 生成随机密码
void _generatePassword() {
  setState(() {
    _isGeneratingPassword = true;
  });

  // 生成包含大小写字母、数字和特殊字符的16位密码
  final password = randomAlphaNumeric(16)
      .replaceRange(0, 0, 'A')
      .replaceRange(1, 1, 'a')
      .replaceRange(2, 2, '1')
      .replaceRange(3, 3, '!');

  setState(() {
    _passwordController.text = password;
    _isGeneratingPassword = false;
  });
}

6. 密码生成算法

我们使用random_string库生成高强度密码,确保包含大小写字母、数字和特殊字符:

/// 生成随机密码
String generateStrongPassword() {
  // 确保包含大小写字母、数字和特殊字符
  const String uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  const String lowercase = 'abcdefghijklmnopqrstuvwxyz';
  const String digits = '0123456789';
  const String special = '!@#%^&*()_+-=[]{}|;:,.<>?';
  
  // 生成随机长度(12-16位)
  final random = Random();
  final length = random.nextInt(5) + 12;
  
  // 确保包含每种字符类型
  String password = '';
  password += uppercase[random.nextInt(uppercase.length)];
  password += lowercase[random.nextInt(lowercase.length)];
  password += digits[random.nextInt(digits.length)];
  password += special[random.nextInt(special.length)];
  
  // 填充剩余长度
  final allChars = uppercase + lowercase + digits + special;
  for (int i = 4; i < length; i++) {
    password += allChars[random.nextInt(allChars.length)];
  }
  
  // 打乱顺序
  return password.split('').shuffle().join();
}

🔍 核心功能流程图

用户操作流程图

拼豆生成器

密码管理

添加密码

查看详情

搜索/筛选

成功

失败

保存

取消

确认

取消

启动应用

选择功能

进入拼豆功能

进入密码列表

操作选择

进入添加密码页

进入密码详情页

显示过滤结果

保存密码

编辑密码

复制密码

删除密码

数据存储流程图

用户操作

UI组件

PasswordProvider

StorageService

JSON序列化

SharedPreferences

本地文件系统

JSON反序列化

📊 开发过程中的挑战与解决方案

挑战 解决方案
依赖版本冲突 固定依赖版本,使用flutter pub outdated检查更新
UI适配问题 使用MediaQuery和Flex布局,适配不同屏幕尺寸
状态管理复杂性 采用Provider单一状态源,简化状态管理
密码安全性 后续计划集成flutter_secure_storage进行加密存储
搜索性能优化 实现本地缓存和异步搜索,提高搜索效率

📝 总结

开发收获

  1. 技术融合:成功将Flutter跨平台开发与鸿蒙系统结合,实现了功能完整的密码管理APP。
  2. 架构设计:采用分层架构设计,使代码结构清晰,易于维护和扩展。
  3. 状态管理:掌握了Provider状态管理的最佳实践,实现了高效的状态同步。
  4. 用户体验:注重UI/UX设计,实现了流畅的用户交互和直观的界面布局。

未来改进方向

  1. 增强安全性:集成flutter_secure_storage进行加密存储,保护用户敏感数据。
  2. 云同步功能:添加云存储支持,实现多设备密码同步。
  3. 生物识别:集成指纹或面部识别,提供更便捷的身份验证方式。
  4. 密码强度检测:添加密码强度评分和改进建议。
  5. 导入/导出功能:支持从其他密码管理器导入数据,以及导出备份功能。

结语

通过鸿蒙+Flutter跨平台开发,我们成功实现了一款功能完整、体验良好的密码管理APP。开发过程中,我们深入理解了跨平台开发的优势和挑战,掌握了多种技术的综合应用。未来,我们将继续优化应用功能,提升用户体验,探索更多跨平台开发的可能性。

鸿蒙系统作为新一代分布式操作系统,具有广阔的发展前景。结合Flutter跨平台框架,开发者可以高效地构建适配多种设备的应用,降低开发成本,提高开发效率。我们相信,鸿蒙+Flutter的组合将在未来的跨平台开发领域发挥越来越重要的作用。


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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐