diff --git a/CHANGELOG.md b/CHANGELOG.md index 35c9b65..efd2614 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file. --- +## [1.3.32] - 2026-04-02 + +### 新增 +- ✨ **个人卡片emoji头像点击切换功能** + - 点击头像可自动切换不同的emoji表情 + - 内置20个精选emoji头像:👤😊🎨🌟🦋🌺🍀🎯🚀💎🌈🎭🦊🐼🦁🐨🦄🐉🔥⚡ + - 添加触觉反馈,提升交互体验 + - 切换时显示SnackBar提示,告知用户新头像 + - 支持收起和展开状态下的头像切换 + - 涉及文件: + - `lib/views/profile/per_card.dart` - 添加头像切换功能 + +--- + ## [1.3.31] - 2026-04-02 ### 优化 @@ -65,18 +79,6 @@ All notable changes to this project will be documented in this file. --- -## [1.3.27] - 2026-04-02 - -### 优化 -- 🎨 **优化调试信息气泡样式** - - 改用透明毛玻璃效果,使用 `barBlur` 实现模糊效果 - - 移除纯色背景,使用半透明黑色背景 (alpha: 0.15) - - 保持 iOS 风格的简洁设计 - - 涉及文件: - - `lib/views/home/home-load.dart` - 修改 showMessage 方法样式 - ---- - ## [1.3.26] - 2026-04-02 ### 优化 @@ -413,17 +415,18 @@ All notable changes to this project will be documented in this file. - ✅ 使用教程页面 - ✅ 全站统计页面 - ✅ 修复 AppBar 标题显示问题 +- ✅ 个人卡片emoji头像切换功能 ### 开发中 - 🚧 更多功能优化 ## 开发进度 -| 功能 | 优先级 | 状态 | -|------|--------|------| -| 使用教程 | 1 | ✅ 已完成 | -| 投稿功能优化 | 2 | ✅ 已完成 | -| 界面美化 | 3 | ✅ 已完成 | -| 数据管理功能 | 1 | ✅ 已完成 | -| 性能优化 | 4 | 🔄 进行中 | -| 新功能开发 | 5 | 📋 计划中 | +| 功能 | 优先级 | 状态 | +| ------------ | ------ | -------- | +| 使用教程 | 1 | ✅ 已完成 | +| 投稿功能优化 | 2 | ✅ 已完成 | +| 界面美化 | 3 | ✅ 已完成 | +| 数据管理功能 | 1 | ✅ 已完成 | +| 性能优化 | 4 | 🔄 进行中 | +| 新功能开发 | 5 | 📋 计划中 | diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 619412f..2980411 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index f04c617..583adce 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index d4dc8e3..5b3ae51 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 4a22e9e..68663db 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index f3c3131..3d06d3f 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/assets/IMG_20260402_172628.png b/assets/IMG_20260402_172628.png new file mode 100644 index 0000000..f77ac19 Binary files /dev/null and b/assets/IMG_20260402_172628.png differ diff --git a/assets/XZ4QCHGE][UUYGCV2G(~88J.png b/assets/XZ4QCHGE][UUYGCV2G(~88J.png deleted file mode 100644 index fb07548..0000000 Binary files a/assets/XZ4QCHGE][UUYGCV2G(~88J.png and /dev/null differ diff --git a/lib/CHANGELOG.md b/lib/CHANGELOG.md index eb1b394..5e065fa 100644 --- a/lib/CHANGELOG.md +++ b/lib/CHANGELOG.md @@ -1,3 +1,16 @@ +## 版本 1.3.3 + +### Bug修复 +- 🔧 **编译错误修复** - 修复三个关键文件的编译错误: + - 修复 `pop-menu.dart` 中缺失的 `GetX` 和 `ThemeController` 导入 + - 修复 `footprint_page.dart` 中缺失的 `PoetryData` 模型导入 + - 修复 `footprint_page.dart` 中错误的包路径导入(从 `package:poetry/` 改为相对路径) + - 修复 `footprint_page.dart` 中 `isDark` 属性名错误(改为 `isDarkMode`) + - 修复 `app-data.dart` 中缺失的 `GetX` 和 `ThemeController` 导入 + - 修复 `ThemeController` 在 const 构造函数中的初始化问题 + - 修复 `ThemeController.instance` 错误调用为 `_themeController` + - 优先级:5 + ## 版本 1.3.2 ### 功能变更 diff --git a/lib/services/get/favorites_controller.dart b/lib/services/get/favorites_controller.dart index 9e7451d..502788e 100644 --- a/lib/services/get/favorites_controller.dart +++ b/lib/services/get/favorites_controller.dart @@ -7,6 +7,8 @@ class FavoritesController extends GetxController { var isGridView = true.obs; var currentTabIndex = 0.obs; var searchQuery = ''.obs; + var sortByTime = true.obs; // true: 按时间排序, false: 按分类排序 + var likesFirst = true.obs; // true: 点赞在前, false: 笔记在前 void toggleViewMode() { isGridView.value = !isGridView.value; @@ -34,24 +36,61 @@ class FavoritesController extends GetxController { mainAxisSize: MainAxisSize.min, children: [ const Text( - '筛选选项', + '排序选项', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 16), ListTile( leading: const Icon(Icons.date_range), title: const Text('按时间排序'), + trailing: Obx( + () => Icon( + sortByTime.value + ? Icons.radio_button_checked + : Icons.radio_button_unchecked, + color: AppConstants.primaryColor, + ), + ), onTap: () { Navigator.pop(context); - Get.snackbar('提示', '按时间排序'); + sortByTime.value = true; + Get.snackbar('提示', '已按时间排序'); + // 触发排序更新 + update(); }, ), ListTile( leading: const Icon(Icons.title), - title: const Text('按标题排序'), + title: const Text('按分类排序'), + trailing: Obx( + () => Icon( + !sortByTime.value + ? Icons.radio_button_checked + : Icons.radio_button_unchecked, + color: AppConstants.primaryColor, + ), + ), onTap: () { Navigator.pop(context); - Get.snackbar('提示', '按标题排序'); + sortByTime.value = false; + Get.snackbar('提示', '已按分类排序'); + // 触发排序更新 + update(); + }, + ), + const Divider(), + ListTile( + leading: const Icon(Icons.swap_vert), + title: Text(likesFirst.value ? '点赞在前' : '笔记在前'), + trailing: Obx( + () => Icon(Icons.swap_vert, color: AppConstants.primaryColor), + ), + onTap: () { + Navigator.pop(context); + likesFirst.value = !likesFirst.value; + Get.snackbar('提示', likesFirst.value ? '点赞在前' : '笔记在前'); + // 触发顺序更新 + update(); }, ), ], @@ -61,10 +100,13 @@ class FavoritesController extends GetxController { } void navigateToSearch() { - Get.toNamed('/search', arguments: searchQuery.value.isEmpty ? null : searchQuery.value); + Get.toNamed( + '/search', + arguments: searchQuery.value.isEmpty ? null : searchQuery.value, + ); } void navigateToCollectNotes() { Get.toNamed('/collect-notes'); } -} \ No newline at end of file +} diff --git a/lib/views/favorites_page.dart b/lib/views/favorites_page.dart index 1640284..12f50f8 100644 --- a/lib/views/favorites_page.dart +++ b/lib/views/favorites_page.dart @@ -27,6 +27,7 @@ class _FavoritesPageState extends State late TabController _tabController; final controller = Get.put(FavoritesController()); final themeController = Get.find(); + final GlobalKey _allListKey = GlobalKey(); @override void initState() { @@ -38,6 +39,18 @@ class _FavoritesPageState extends State _tabController.addListener(() { controller.setCurrentTabIndex(_tabController.index); }); + + // 监听排序变化,更新AllListPage + ever(controller.sortByTime, (bool newSortByTime) { + if (_allListKey.currentState != null && mounted) { + _allListKey.currentState!.sortByTime(newSortByTime); + } + }); + ever(controller.likesFirst, (bool newLikesFirst) { + if (_allListKey.currentState != null && mounted) { + _allListKey.currentState!.toggleLikesFirst(); + } + }); } @override @@ -58,22 +71,9 @@ class _FavoritesPageState extends State tabController: _tabController, tabBarScrollable: true, tabLabelPadding: const EdgeInsets.symmetric(horizontal: 10), - actions: [ - IconButton( - icon: Icon( - controller.isGridView.value ? Icons.view_list : Icons.grid_view, - color: isDark ? Colors.white70 : null, - ), - onPressed: controller.toggleViewMode, - ), - IconButton( - icon: Icon( - Icons.filter_list, - color: isDark ? Colors.white70 : null, - ), - onPressed: () => controller.showFilterOptions(context), - ), - ], + backgroundColor: isDark ? const Color(0xFF1A1A1A) : Colors.white, + foregroundColor: isDark ? Colors.white : Colors.black87, + actions: _buildAppBarActions(controller), ), body: Column( children: [ @@ -88,29 +88,44 @@ class _FavoritesPageState extends State ), ], ), - floatingActionButton: _buildFloatingButton(controller), - floatingActionButtonLocation: FloatingActionButtonLocation.miniEndFloat, ); }); } - Widget _buildFloatingButton(FavoritesController controller) { + // 构建AppBar操作按钮 + List _buildAppBarActions(FavoritesController controller) { final currentCategory = controller.categories[controller.currentTabIndex.value]; + final isDark = themeController.isDarkMode; - if (currentCategory != '笔记') { - return const SizedBox.shrink(); + List actions = [ + IconButton( + icon: Icon( + controller.isGridView.value ? Icons.view_list : Icons.grid_view, + color: isDark ? Colors.white70 : null, + ), + onPressed: controller.toggleViewMode, + ), + IconButton( + icon: Icon(Icons.filter_list, color: isDark ? Colors.white70 : null), + onPressed: () => controller.showFilterOptions(context), + ), + ]; + + // 只在笔记页面显示添加笔记按钮 + if (currentCategory == '笔记') { + actions.insert( + 0, + IconButton( + icon: Icon(Icons.add, color: isDark ? Colors.white70 : null), + onPressed: () { + Get.to(const CollectNotesPage()); + }, + ), + ); } - return FloatingActionButton( - onPressed: () { - Get.to(const CollectNotesPage()); - }, - child: const Icon(Icons.add), - backgroundColor: AppConstants.primaryColor, - heroTag: 'notes_fab', - elevation: 4, - ); + return actions; } Widget _buildSearchBar(FavoritesController controller, bool isDark) { @@ -122,7 +137,7 @@ class _FavoritesPageState extends State 16, ), decoration: BoxDecoration( - color: isDark ? Colors.grey[850] : Colors.grey[100], + color: isDark ? const Color(0xFF2A2A2A) : Colors.grey[100], borderRadius: BorderRadius.circular(12), ), child: TextField( @@ -138,14 +153,14 @@ class _FavoritesPageState extends State }, decoration: InputDecoration( hintText: '点按搜索全站诗词…', - hintStyle: TextStyle(color: isDark ? Colors.grey[500] : Colors.grey), + hintStyle: TextStyle(color: isDark ? Colors.grey[400] : Colors.grey), prefixIcon: Icon( Icons.search, - color: isDark ? Colors.grey[500] : Colors.grey, + color: isDark ? Colors.grey[400] : Colors.grey, ), suffixIcon: Icon( Icons.chevron_right, - color: isDark ? Colors.grey[500] : Colors.grey[500], + color: isDark ? Colors.grey[400] : Colors.grey[500], ), border: InputBorder.none, contentPadding: const EdgeInsets.symmetric( @@ -158,9 +173,15 @@ class _FavoritesPageState extends State } Widget _buildFavoriteList(String category, FavoritesController controller) { + final isDark = themeController.isDarkMode; + // 如果是"全部"标签,显示统一的收藏列表(点赞+笔记) if (category == '全部') { - return const AllListPage(); + return AllListPage( + key: _allListKey, + initialSortByTime: controller.sortByTime.value, + initialLikesFirst: controller.likesFirst.value, + ); } // 如果是"点赞"标签,显示点赞内容管理器 @@ -176,6 +197,8 @@ class _FavoritesPageState extends State // 其他标签显示占位内容,但支持下拉刷新 return RefreshIndicator( onRefresh: controller.refreshContent, + color: AppConstants.primaryColor, + backgroundColor: isDark ? const Color(0xFF2A2A2A) : Colors.white, child: _buildPlaceholderContent(category), ); } diff --git a/lib/views/footprint/all_list.dart b/lib/views/footprint/all_list.dart index 2f7bf30..1690f94 100644 --- a/lib/views/footprint/all_list.dart +++ b/lib/views/footprint/all_list.dart @@ -30,21 +30,37 @@ class UnifiedCard { } class AllListPage extends StatefulWidget { - const AllListPage({super.key}); + final bool? initialSortByTime; + final bool? initialLikesFirst; + + const AllListPage({ + super.key, + this.initialSortByTime, + this.initialLikesFirst, + }); @override - State createState() => _AllListPageState(); + State createState() => AllListPageState(); } -class _AllListPageState extends State { +class AllListPageState extends State { List _cards = []; bool _isLoading = false; + bool _sortByTime = true; // true: 按时间排序, false: 按分类排序 + bool _likesFirst = true; // true: 点赞在前, false: 笔记在前 StreamSubscription? _networkSubscription; final ThemeController _themeController = Get.find(); @override void initState() { super.initState(); + // 应用初始化排序参数 + if (widget.initialSortByTime != null) { + _sortByTime = widget.initialSortByTime!; + } + if (widget.initialLikesFirst != null) { + _likesFirst = widget.initialLikesFirst!; + } _loadAllData(); _listenToNetworkEvents(); } @@ -115,8 +131,32 @@ class _AllListPageState extends State { ); } - // 按时间排序(最新的在前) - allCards.sort((a, b) => b.time.compareTo(a.time)); + // 根据状态进行排序 + if (_sortByTime) { + // 按时间排序(最新的在前) + allCards.sort((a, b) => b.time.compareTo(a.time)); + } else { + // 按分类排序,点赞在前,笔记在后 + allCards.sort((a, b) { + // 先按类型排序 + final typeCompare = a.type.index.compareTo(b.type.index); + if (typeCompare != 0) return typeCompare; + + // 同类型按时间排序 + return b.time.compareTo(a.time); + }); + + // 如果笔记在前,则重新排序 + if (!_likesFirst) { + allCards.sort((a, b) { + if (a.type != b.type) { + // 笔记在前,笔记类型排在前面 + return a.type == CardType.note ? -1 : 1; + } + return b.time.compareTo(a.time); + }); + } + } if (mounted) { setState(() { @@ -730,4 +770,50 @@ class _AllListPageState extends State { ), ); } + + // 公开的排序方法,供外部调用 + void sortByTime(bool sortByTime) { + if (_sortByTime != sortByTime) { + setState(() { + _sortByTime = sortByTime; + _applySorting(); + }); + } + } + + void toggleLikesFirst() { + setState(() { + _likesFirst = !_likesFirst; + _applySorting(); + }); + } + + // 应用排序逻辑 + void _applySorting() { + if (_sortByTime) { + // 按时间排序(最新的在前) + _cards.sort((a, b) => b.time.compareTo(a.time)); + } else { + // 按分类排序,点赞在前,笔记在后 + _cards.sort((a, b) { + // 先按类型排序 + final typeCompare = a.type.index.compareTo(b.type.index); + if (typeCompare != 0) return typeCompare; + + // 同类型按时间排序 + return b.time.compareTo(a.time); + }); + + // 如果笔记在前,则重新排序 + if (!_likesFirst) { + _cards.sort((a, b) { + if (a.type != b.type) { + // 笔记在前,笔记类型排在前面 + return a.type == CardType.note ? -1 : 1; + } + return b.time.compareTo(a.time); + }); + } + } + } } diff --git a/lib/views/footprint/footprint_page.dart b/lib/views/footprint/footprint_page.dart index 8cf8a01..b501600 100644 --- a/lib/views/footprint/footprint_page.dart +++ b/lib/views/footprint/footprint_page.dart @@ -9,7 +9,8 @@ import 'dart:async' show StreamSubscription; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:poes/controllers/history_controller.dart'; +import '../../../models/poetry_model.dart'; +import '../../../controllers/history_controller.dart'; import '../../../constants/app_constants.dart'; import '../../../utils/http/poetry_api.dart'; import '../../../services/network_listener_service.dart'; @@ -118,9 +119,11 @@ class _FootprintPageState extends State backgroundColor: Colors.transparent, builder: (context) => Container( height: MediaQuery.of(context).size.height * 0.8, - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( + decoration: BoxDecoration( + color: _themeController.isDarkMode + ? const Color(0xFF2A2A2A) + : Colors.white, + borderRadius: const BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20), ), diff --git a/lib/views/home/home_part.dart b/lib/views/home/home_part.dart index f288048..78f7e4e 100644 --- a/lib/views/home/home_part.dart +++ b/lib/views/home/home_part.dart @@ -655,7 +655,7 @@ class _PoetryCardState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '诗词原文', + '原文|赏析', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w600, diff --git a/lib/views/profile/app-info.dart b/lib/views/profile/app-info.dart index c3ded83..f41523a 100644 --- a/lib/views/profile/app-info.dart +++ b/lib/views/profile/app-info.dart @@ -958,26 +958,26 @@ class _AppInfoPageState extends State { ], ), ), - Divider(height: 1, color: isDark ? Colors.grey[800] : null), - Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildUpdateItem('版本 1.2.40', '2026-03-27', [ - '新增:主题个性化页面', - '新增:设计风格卡片', - '优化:界面布局和响应式设计', - ], isDark), - const SizedBox(height: 16), - _buildUpdateItem('版本 1.2.39', '2026-03-27', [ - '修复:引导页滑动问题', - '优化:左侧进度条位置', - '新增:协议内容焦点功能', - ], isDark), - ], - ), - ), + // Divider(height: 1, color: isDark ? Colors.grey[800] : null), + // Padding( + // padding: const EdgeInsets.all(16), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // _buildUpdateItem('版本 1.2.40', '2026-03-27', [ + // '新增:主题个性化页面', + // '新增:设计风格卡片', + // '优化:界面布局和响应式设计', + // ], isDark), + // const SizedBox(height: 16), + // _buildUpdateItem('版本 1.2.39', '2026-03-27', [ + // '修复:引导页滑动问题', + // '优化:左侧进度条位置', + // '新增:协议内容焦点功能', + // ], isDark), + // ], + // ), + // ), ], ), ); diff --git a/lib/views/profile/components/pop-menu.dart b/lib/views/profile/components/pop-menu.dart index 5fdbc1b..e0d0cc4 100644 --- a/lib/views/profile/components/pop-menu.dart +++ b/lib/views/profile/components/pop-menu.dart @@ -2,8 +2,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:share_plus/share_plus.dart'; +import 'package:get/get.dart'; import '../../../constants/app_constants.dart'; import '../../../services/isweb/wakelock_service.dart'; +import '../../../services/get/theme_controller.dart'; import '../guide/beginner_page.dart'; import 'dart:io' as io; @@ -14,7 +16,7 @@ class PopMenu extends StatelessWidget { final VoidCallback? onDarkMode; final VoidCallback? onSettings; - const PopMenu({ + PopMenu({ super.key, this.onRefresh, this.onEdit, @@ -23,6 +25,8 @@ class PopMenu extends StatelessWidget { this.onSettings, }); + final ThemeController _themeController = Get.find(); + static Future shareApp(BuildContext context) async { try { const String shareText = '情景诗词App - 一款优雅的诗词学习应用,包含丰富的诗词内容和答题功能'; @@ -124,42 +128,78 @@ class PopMenu extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.vertical(top: Radius.circular(20)), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // 顶部拖拽条 - Container( - width: 40, - height: 4, - margin: const EdgeInsets.only(top: 8), - decoration: BoxDecoration( - color: Colors.grey[300]!, - borderRadius: BorderRadius.circular(2), + return Obx(() { + final isDark = _themeController.isDarkMode; + + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: isDark ? const Color(0xFF2A2A2A) : Colors.white, + borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(isDark ? 76 : 26), + blurRadius: 10, + offset: const Offset(0, -2), + ), + ], + ), + child: Material( + color: Colors.transparent, + child: InkWell( + onTap: () { + SystemNavigator.pop(); + }, + child: Container( + width: double.infinity, + padding: const EdgeInsets.symmetric(vertical: 20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // 顶部拖拽条 + Container( + width: 40, + height: 4, + margin: const EdgeInsets.only(top: 8), + decoration: BoxDecoration( + color: isDark ? Colors.grey[600]! : Colors.grey[300]!, + borderRadius: BorderRadius.circular(2), + ), + ), + // 选项列表 + _buildBottomSheetItem( + context, + '刷新数据', + Icons.refresh, + onRefresh, + ), + _buildBottomSheetItem(context, '分享软件', Icons.share, () { + shareApp(context); + }), + _buildBottomSheetItem(context, '使用教程', Icons.menu_book, () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => const BeginnerPage(), + ), + ); + }), + _buildBottomSheetItem( + context, + '取消', + Icons.settings, + onSettings, + ), + const SizedBox(height: 20), + _buildBottomSheetItem(context, '返回桌面', Icons.exit_to_app, () { + SystemNavigator.pop(); + }), + ], + ), ), ), - // 选项列表 - _buildBottomSheetItem(context, '刷新数据', Icons.refresh, onRefresh), - _buildBottomSheetItem(context, '分享软件', Icons.share, () { - shareApp(context); - }), - _buildBottomSheetItem(context, '使用教程', Icons.menu_book, () { - Navigator.of(context).push( - MaterialPageRoute(builder: (_) => const BeginnerPage()), - ); - }), - _buildBottomSheetItem(context, '取消', Icons.settings, onSettings), - const SizedBox(height: 20), - _buildBottomSheetItem(context, '返回桌面', Icons.exit_to_app, () { - SystemNavigator.pop(); - }), - ], - ), - ); + ), + ); + }); } Widget _buildBottomSheetItem( @@ -168,9 +208,17 @@ class PopMenu extends StatelessWidget { IconData icon, VoidCallback? onTap, ) { + final isDark = _themeController.isDarkMode; + return ListTile( - leading: Icon(icon, color: AppConstants.primaryColor), - title: Text(title), + leading: Icon( + icon, + color: isDark ? Colors.white70 : AppConstants.primaryColor, + ), + title: Text( + title, + style: TextStyle(color: isDark ? Colors.white70 : Colors.black87), + ), onTap: () { Navigator.pop(context); HapticFeedback.lightImpact(); diff --git a/lib/views/profile/guide/app-data.dart b/lib/views/profile/guide/app-data.dart index db82dbd..7f698cf 100644 --- a/lib/views/profile/guide/app-data.dart +++ b/lib/views/profile/guide/app-data.dart @@ -1,9 +1,11 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:path_provider/path_provider.dart'; import '../../../constants/app_constants.dart'; +import '../../../services/get/theme_controller.dart'; /// 时间: 2026-03-27 /// 功能: 应用数据管理页面 @@ -28,6 +30,8 @@ class _AppDataPageState extends State { int _cacheBytes = 0; int _dataBytes = 0; + final ThemeController _themeController = Get.find(); + @override void initState() { super.initState(); @@ -492,41 +496,41 @@ class _AppDataPageState extends State { @override Widget build(BuildContext context) { - return Scaffold( - backgroundColor: const Color(0xFFF5F5F5), - appBar: AppBar( - title: Text( - '应用数据', - style: TextStyle( - color: AppConstants.primaryColor, - fontWeight: FontWeight.bold, + return Obx(() { + final isDark = _themeController.isDarkMode; + + return Scaffold( + backgroundColor: isDark + ? const Color(0xFF1A1A1A) + : const Color(0xFFF5F5F5), + appBar: AppBar( + title: const Text( + '应用数据', + style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold), ), + backgroundColor: isDark + ? const Color(0xFF2A2A2A) + : AppConstants.primaryColor, + iconTheme: IconThemeData(color: Colors.white), ), - backgroundColor: Colors.white, - elevation: 0, - centerTitle: true, - leading: IconButton( - icon: Icon(Icons.arrow_back, color: AppConstants.primaryColor), - onPressed: () => Navigator.of(context).pop(), - ), - ), - body: _isLoading - ? const Center(child: CircularProgressIndicator()) - : ListView( - padding: const EdgeInsets.all(16), - children: [ - _buildDataOverviewCard(), - const SizedBox(height: 16), - _buildDataManagementCard(), - const SizedBox(height: 16), - _buildDataBackupCard(), - const SizedBox(height: 16), - _buildDangerZoneCard(), - const SizedBox(height: 24), - _buildBottomInfo(), - ], - ), - ); + body: _isLoading + ? const Center(child: CircularProgressIndicator()) + : ListView( + padding: const EdgeInsets.all(16), + children: [ + _buildDataOverviewCard(), + const SizedBox(height: 16), + _buildDataManagementCard(), + const SizedBox(height: 16), + _buildDataBackupCard(), + const SizedBox(height: 16), + _buildDangerZoneCard(), + const SizedBox(height: 24), + _buildBottomInfo(), + ], + ), + ); + }); } Widget _buildDataOverviewCard() { @@ -578,35 +582,55 @@ class _AppDataPageState extends State { } Widget _buildDataItem(String label, String value) { + final isDark = _themeController.isDarkMode; + return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(label, style: const TextStyle(fontSize: 14)), - Text(value, style: TextStyle(fontSize: 14, color: Colors.grey[600])), + Text( + label, + style: TextStyle( + fontSize: 14, + color: isDark ? Colors.white70 : Colors.black87, + ), + ), + Text( + value, + style: TextStyle( + fontSize: 14, + color: isDark ? Colors.grey[400] : Colors.grey[600], + ), + ), ], ), ); } Widget _buildDivider() { + final isDark = _themeController.isDarkMode; + return Divider( height: 1, indent: 16, endIndent: 16, - color: Colors.grey[200], + color: isDark ? Colors.grey[700] : Colors.grey[200], ); } Widget _buildDataManagementCard() { + final isDark = _themeController.isDarkMode; + return Container( decoration: BoxDecoration( - color: Colors.white, + color: isDark ? const Color(0xFF2A2A2A) : Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.05), + color: isDark + ? Colors.black.withValues(alpha: 0.2) + : Colors.black.withValues(alpha: 0.05), blurRadius: 10, offset: const Offset(0, 2), ), @@ -662,13 +686,17 @@ class _AppDataPageState extends State { } Widget _buildDataBackupCard() { + final isDark = _themeController.isDarkMode; + return Container( decoration: BoxDecoration( - color: Colors.white, + color: isDark ? const Color(0xFF2A2A2A) : Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.05), + color: isDark + ? Colors.black.withValues(alpha: 0.2) + : Colors.black.withValues(alpha: 0.05), blurRadius: 10, offset: const Offset(0, 2), ), @@ -724,13 +752,17 @@ class _AppDataPageState extends State { } Widget _buildDangerZoneCard() { + final isDark = _themeController.isDarkMode; + return Container( decoration: BoxDecoration( - color: Colors.white, + color: isDark ? const Color(0xFF2A2A2A) : Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( - color: Colors.black.withValues(alpha: 0.05), + color: isDark + ? Colors.black.withValues(alpha: 0.2) + : Colors.black.withValues(alpha: 0.05), blurRadius: 10, offset: const Offset(0, 2), ), @@ -788,6 +820,8 @@ class _AppDataPageState extends State { Color color, VoidCallback onTap, ) { + final isDark = _themeController.isDarkMode; + return InkWell( onTap: onTap, borderRadius: BorderRadius.circular(8), @@ -811,20 +845,28 @@ class _AppDataPageState extends State { children: [ Text( title, - style: const TextStyle( + style: TextStyle( fontSize: 15, fontWeight: FontWeight.w500, + color: isDark ? Colors.white : Colors.black87, ), ), const SizedBox(height: 2), Text( subtitle, - style: TextStyle(fontSize: 12, color: Colors.grey[600]), + style: TextStyle( + fontSize: 12, + color: isDark ? Colors.grey[400] : Colors.grey[600], + ), ), ], ), ), - Icon(Icons.chevron_right, color: Colors.grey[400]), + Icon( + Icons.chevron_right, + color: isDark ? Colors.grey[500] : Colors.grey[400], + size: 20, + ), ], ), ), @@ -832,23 +874,32 @@ class _AppDataPageState extends State { } Widget _buildBottomInfo() { + final isDark = _themeController.isDarkMode; + return Center( child: Column( children: [ - Icon(Icons.info_outline, color: Colors.grey[400], size: 32), + Icon( + Icons.info_outline, + color: isDark ? Colors.grey[500] : Colors.grey[400], + size: 32, + ), const SizedBox(height: 8), Text( '数据安全提示', style: TextStyle( fontSize: 14, - color: Colors.grey[600], + color: isDark ? Colors.grey[300] : Colors.grey[600], fontWeight: FontWeight.w500, ), ), const SizedBox(height: 4), Text( '清空数据前请先备份重要数据', - style: TextStyle(fontSize: 12, color: Colors.grey[500]), + style: TextStyle( + fontSize: 12, + color: isDark ? Colors.grey[400] : Colors.grey[500], + ), ), ], ), diff --git a/lib/views/profile/per_card.dart b/lib/views/profile/per_card.dart index 44ab7b7..2ad2a40 100644 --- a/lib/views/profile/per_card.dart +++ b/lib/views/profile/per_card.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'dart:math'; import 'package:flutter/services.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:get/get.dart'; import '../../constants/app_constants.dart'; import '../../services/network_listener_service.dart'; import 'guide/tongji.dart'; @@ -41,6 +42,7 @@ class PersonalCardState extends State { bool _isEditingNickname = false; bool _isUserPlanJoined = false; late TextEditingController _nicknameController; + int _currentAvatarIndex = 0; // 累计数据 int _totalViews = 0; @@ -229,6 +231,29 @@ class PersonalCardState extends State { "新的一年,愿你拥有🐲🐴精神,事业如🐲头腾飞,家庭和睦🏠,幸福美满❤️!", ]; + final List _avatarEmojis = [ + '👤', + '😊', + '🎨', + '🌟', + '🦋', + '🌺', + '🍀', + '🎯', + '🚀', + '💎', + '🌈', + '🎭', + '🦊', + '🐼', + '🦁', + '🐨', + '🦄', + '🐉', + '🔥', + '⚡', + ]; + String _getRandomTip() { final random = Random(); return _tips[random.nextInt(_tips.length)]; @@ -240,6 +265,23 @@ class PersonalCardState extends State { }); } + void _switchAvatar() { + setState(() { + _currentAvatarIndex = (_currentAvatarIndex + 1) % _avatarEmojis.length; + widget.userData['avatar'] = _avatarEmojis[_currentAvatarIndex]; + }); + + // 添加触觉反馈 + HapticFeedback.lightImpact(); + + // 显示切换提示 + Get.snackbar( + '头像切换', + '头像已切换为 ${_avatarEmojis[_currentAvatarIndex]}', + duration: const Duration(seconds: 1), + ); + } + @override Widget build(BuildContext context) { return Container( @@ -301,7 +343,10 @@ class PersonalCardState extends State { children: [ // 头像 GestureDetector( - onTap: widget.onAvatarTap, + onTap: () { + _switchAvatar(); + widget.onAvatarTap?.call(); + }, child: Stack( children: [ Container( @@ -416,7 +461,10 @@ class PersonalCardState extends State { children: [ // 头像 GestureDetector( - onTap: widget.onAvatarTap, + onTap: () { + _switchAvatar(); + widget.onAvatarTap?.call(); + }, child: Stack( children: [ Container( diff --git a/lib/views/profile/profile_page.dart b/lib/views/profile/profile_page.dart index 9b14d47..23ca504 100644 --- a/lib/views/profile/profile_page.dart +++ b/lib/views/profile/profile_page.dart @@ -241,7 +241,10 @@ class ProfilePage extends StatelessWidget { borderRadius: BorderRadius.circular(8), ), ), - child: const Text('开始诗词答题', style: TextStyle(fontSize: 16)), + child: const Text( + '开始诗词答题', + style: TextStyle(fontSize: 16, color: Colors.white), + ), ), ), ], diff --git a/lib/views/profile/settings/app_fun.dart b/lib/views/profile/settings/app_fun.dart index af46948..9907274 100644 --- a/lib/views/profile/settings/app_fun.dart +++ b/lib/views/profile/settings/app_fun.dart @@ -8,6 +8,8 @@ import '../../../services/get/tap_liquid_glass_controller.dart'; import '../../../utils/audio_manager.dart'; import './widgets.dart'; import '../../home/set/home-load.dart'; +import '../../profile/theme/app-diy.dart'; +import '../../footprint/collect_notes.dart'; import '../../../controllers/load/locally.dart'; /// 时间: 2026-03-26 @@ -668,7 +670,7 @@ class _AppFunSettingsPageState extends State { ), const SizedBox(height: 12), Text( - AppConstants.appName, + '设置建议', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, @@ -677,17 +679,87 @@ class _AppFunSettingsPageState extends State { ), const SizedBox(height: 4), Text( - '版本 ${AppConstants.appVersion}', + '是否在找,主题风格', style: TextStyle( fontSize: 13, color: isDark ? Colors.grey[400] : Colors.grey[600], ), ), + const SizedBox(height: 16), + Row( + children: [ + Expanded( + child: _buildActionButton( + '主题风格', + '自定义应用主题', + Icons.palette, + Colors.blue, + () => Get.to(() => const AppDiyPage()), + ), + ), + const SizedBox(width: 12), + Expanded( + child: _buildActionButton( + '创建笔记', + '快速创建新笔记', + Icons.note_add, + Colors.green, + () => Get.to(() => const CollectNotesPage()), + ), + ), + ], + ), ], ), ); } + Widget _buildActionButton( + String title, + String subtitle, + IconData icon, + Color color, + VoidCallback onTap, + ) { + final isDark = _themeController.isDarkMode; + + return InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(8), + child: Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + color: color.withValues(alpha: 0.1), + borderRadius: BorderRadius.circular(8), + border: Border.all(color: color.withValues(alpha: 0.2), width: 1), + ), + child: Column( + children: [ + Icon(icon, color: color, size: 24), + const SizedBox(height: 4), + Text( + title, + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: isDark ? Colors.white : Colors.black87, + ), + ), + const SizedBox(height: 2), + Text( + subtitle, + style: TextStyle( + fontSize: 10, + color: isDark ? Colors.grey[400] : Colors.grey[600], + ), + textAlign: TextAlign.center, + ), + ], + ), + ), + ); + } + void _showSnackBar(String message) { ScaffoldMessenger.of( context, diff --git a/lib/views/profile/settings/learn-us.dart b/lib/views/profile/settings/learn-us.dart index 7460067..892ea2d 100644 --- a/lib/views/profile/settings/learn-us.dart +++ b/lib/views/profile/settings/learn-us.dart @@ -783,7 +783,7 @@ class LearnUsPage extends StatelessWidget { ), const SizedBox(width: 12), Text( - '备案信息', + 'ICP备案信息', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, @@ -799,16 +799,43 @@ class LearnUsPage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - '滇ICP备2025002147号-2A', - style: TextStyle( - fontSize: 14, - color: isDark ? Colors.grey[300] : Colors.grey[700], + GestureDetector( + onTap: () { + Clipboard.setData( + const ClipboardData(text: '滇ICP备2022000863号-13'), + ); + Get.snackbar( + '复制成功', + '备案号已复制到剪贴板', + duration: const Duration(seconds: 1), + ); + }, + child: Row( + children: [ + Expanded( + child: Text( + '滇ICP备2022000863号-13', + style: TextStyle( + fontSize: 14, + color: isDark ? Colors.grey[300] : Colors.grey[700], + decoration: TextDecoration.underline, + decorationColor: isDark + ? Colors.grey[400] + : Colors.grey[600], + ), + ), + ), + Icon( + Icons.copy, + size: 16, + color: isDark ? Colors.grey[400] : Colors.grey[600], + ), + ], ), ), const SizedBox(height: 4), Text( - '弥勒市朋普镇微风暴网络科技工作室', + 'APP核准备案号', style: TextStyle( fontSize: 13, color: isDark ? Colors.grey[400] : Colors.grey[600], diff --git a/lib/views/profile/theme/app-diy.dart b/lib/views/profile/theme/app-diy.dart index bd4707b..eb923c8 100644 --- a/lib/views/profile/theme/app-diy.dart +++ b/lib/views/profile/theme/app-diy.dart @@ -89,7 +89,8 @@ class _AppDiyPageState extends State { style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), SizedBox(height: 12), - Text('• 当前设置仅当前页面生效'), + Text('• 当前仅支持设置深色模式'), + Text('• 其他设置仅当前页面生效'), Text('• 后续版本将陆续支持'), Text('• 可提前预览主题风格设置'), SizedBox(height: 12), diff --git a/ohos/AppScope/app.json5 b/ohos/AppScope/app.json5 index cd55b32..3b9b899 100644 --- a/ohos/AppScope/app.json5 +++ b/ohos/AppScope/app.json5 @@ -2,7 +2,7 @@ "app": { "bundleName": "app.wushu.poes", "vendor": "微风暴", - "versionCode": 26040101, + "versionCode": 26040202, "versionName": "1.4.1", "icon": "$media:app_icon", "label": "$string:app_name" diff --git a/ohos/AppScope/resources/base/media/app_icon.png b/ohos/AppScope/resources/base/media/app_icon.png index f3c3131..922ee30 100644 Binary files a/ohos/AppScope/resources/base/media/app_icon.png and b/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/build-profile.json5 b/ohos/build-profile.json5 index 0fbc844..07ce7ab 100644 --- a/ohos/build-profile.json5 +++ b/ohos/build-profile.json5 @@ -7,11 +7,11 @@ "material": { "certpath": "C:\\Users\\无书\\.ohos\\config\\default_ohos_hWyPJmkoRvc13RxcUC3NSaiad5bS6MHBrY9nkKd-288=.cer", "keyAlias": "debugKey", - "keyPassword": "0000001BD23894F1C728472C15E1CFD5A35D53C14AAA5CB668AFB407AA9A688319F47FCE244C0526BD541D", + "keyPassword": "0000001B30697BA50DA29BFA78D2DF8926B3F3FAA6059A0E213B0E5DD008398846B8A2A07001F7593C1A90", "profile": "C:\\Users\\无书\\.ohos\\config\\default_ohos_hWyPJmkoRvc13RxcUC3NSaiad5bS6MHBrY9nkKd-288=.p7b", "signAlg": "SHA256withECDSA", "storeFile": "C:\\Users\\无书\\.ohos\\config\\default_ohos_hWyPJmkoRvc13RxcUC3NSaiad5bS6MHBrY9nkKd-288=.p12", - "storePassword": "0000001B9419E1D96E288BAD3910A8E0B1BE70A8D56BA67EEA0AF12AD6C4B3035E526CA218229DDEEEB875" + "storePassword": "0000001B4AC7202D6AFC70972F3CA3C16E2CD3A6D66AEE7DB8084FEE06BD59E80DB37F1A0D707660A5D3A1" } }, { @@ -20,11 +20,11 @@ "material": { "certpath": "D:/zhshu/520kiss123Release .cer", "keyAlias": "520kiss123", - "keyPassword": "0000001A770D27C715C2C76CD225BA13525637D1AB00DD6553534835E2BFB6E3C99FED62A418FF950EE3", + "keyPassword": "0000001A6DD333EC625F896ED76F7787E3B2A3090EB0E84E2487317FAE80D669C4842267A56560A46B1A", "profile": "D:/zhshu/520kiss123Release .p7b", "signAlg": "SHA256withECDSA", "storeFile": "D:/zhshu/520kiss123.p12", - "storePassword": "0000001A9357A9E29E7DA423D4BA05B8410FA43D4D4364A3D93B4478502F07FAE3CDFC2EB4CD5B945CF8" + "storePassword": "0000001A73F79AFE95A61248456E9C5B91B885C72563DE86E6CBF364E1257AB5DF55E0FC7F7D2353C7A2" } } ], diff --git a/ohos/entry/src/main/resources/base/media/icon.png b/ohos/entry/src/main/resources/base/media/icon.png index 4a22e9e..a5ca23e 100644 Binary files a/ohos/entry/src/main/resources/base/media/icon.png and b/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/entry/src/main/resources/base/media/icon_216.png b/ohos/entry/src/main/resources/base/media/icon_216.png index 74ade02..cd03afa 100644 Binary files a/ohos/entry/src/main/resources/base/media/icon_216.png and b/ohos/entry/src/main/resources/base/media/icon_216.png differ diff --git a/ohos/entry/src/main/resources/base/media/icon_48.png b/ohos/entry/src/main/resources/base/media/icon_48.png index f04c617..8d4fb33 100644 Binary files a/ohos/entry/src/main/resources/base/media/icon_48.png and b/ohos/entry/src/main/resources/base/media/icon_48.png differ diff --git a/ohos/entry/src/main/resources/base/media/icon_512.png b/ohos/entry/src/main/resources/base/media/icon_512.png index dcdf4d3..70953ec 100644 Binary files a/ohos/entry/src/main/resources/base/media/icon_512.png and b/ohos/entry/src/main/resources/base/media/icon_512.png differ diff --git a/ohos/entry/src/main/resources/base/media/icon_72.png b/ohos/entry/src/main/resources/base/media/icon_72.png index 619412f..c05821f 100644 Binary files a/ohos/entry/src/main/resources/base/media/icon_72.png and b/ohos/entry/src/main/resources/base/media/icon_72.png differ diff --git a/ohos/entry/src/main/resources/base/media/icon_96.png b/ohos/entry/src/main/resources/base/media/icon_96.png index d4dc8e3..f53f8af 100644 Binary files a/ohos/entry/src/main/resources/base/media/icon_96.png and b/ohos/entry/src/main/resources/base/media/icon_96.png differ diff --git a/resize_android_icons.py b/resize_android_icons.py new file mode 100644 index 0000000..882b29c --- /dev/null +++ b/resize_android_icons.py @@ -0,0 +1,40 @@ +from PIL import Image +import os + +# 原始图片路径 +original_image_path = r"e:\project\flutter\f3\flutter_application_2\assets\audios\IMG_20260402_170051.png" + +# 安卓端图标目录 +android_res_dir = r"e:\project\flutter\f3\flutter_application_2\android\app\src\main\res" + +# 安卓端图标尺寸配置 (density: (width, height)) +android_sizes = { + "mdpi": (48, 48), + "hdpi": (72, 72), + "xhdpi": (144, 144), + "xxhdpi": (96, 96), + "xxxhdpi": (192, 192), +} + +try: + # 打开原始图片 + with Image.open(original_image_path) as img: + print(f"原始图片尺寸: {img.size}") + + # 为每个密度生成图标 + for density, size in android_sizes.items(): + # 调整尺寸 + resized_img = img.resize(size, Image.Resampling.LANCZOS) + + # 构建输出路径 + output_dir = os.path.join(android_res_dir, f"mipmap-{density}") + os.makedirs(output_dir, exist_ok=True) + + output_path = os.path.join(output_dir, "ic_launcher.png") + resized_img.save(output_path) + print(f"已保存 {density} ({size[0]}x{size[1]}) 图标到: {output_path}") + + print("\n安卓端所有图标尺寸调整完成!") + +except Exception as e: + print(f"处理图片时出错: {e}") diff --git a/resize_icons.py b/resize_icons.py new file mode 100644 index 0000000..6095782 --- /dev/null +++ b/resize_icons.py @@ -0,0 +1,52 @@ +from PIL import Image +import os + +# 原始图片路径 +original_image_path = r"e:\project\flutter\f3\flutter_application_2\assets\audios\IMG_20260402_170051.png" + +# 输出目录 +app_scope_dir = r"e:\project\flutter\f3\flutter_application_2\ohos\AppScope\resources\base\media" +entry_media_dir = r"e:\project\flutter\f3\flutter_application_2\ohos\entry\src\main\resources\base\media" + +# 确保目录存在 +os.makedirs(app_scope_dir, exist_ok=True) +os.makedirs(entry_media_dir, exist_ok=True) + +try: + # 打开原始图片 + with Image.open(original_image_path) as img: + print(f"原始图片尺寸: {img.size}") + + # 调整为 288x288 用于 app_icon.png + img_288 = img.resize((288, 288), Image.Resampling.LANCZOS) + app_icon_path = os.path.join(app_scope_dir, "app_icon.png") + img_288.save(app_icon_path) + print(f"已保存 288x288 图标到: {app_icon_path}") + + # 调整为 1024x1024 用于 entry 目录的图标 + img_1024 = img.resize((1024, 1024), Image.Resampling.LANCZOS) + + # 保存到 entry 目录 + entry_icon_path = os.path.join(entry_media_dir, "icon.png") + img_1024.save(entry_icon_path) + print(f"已保存 1024x1024 图标到: {entry_icon_path}") + + # 保存其他尺寸 + sizes = [ + (216, "icon_216.png"), + (48, "icon_48.png"), + (512, "icon_512.png"), + (72, "icon_72.png"), + (96, "icon_96.png"), + ] + + for size, filename in sizes: + resized_img = img.resize((size, size), Image.Resampling.LANCZOS) + output_path = os.path.join(entry_media_dir, filename) + resized_img.save(output_path) + print(f"已保存 {size}x{size} 图标到: {output_path}") + + print("\n所有图标尺寸调整完成!") + +except Exception as e: + print(f"处理图片时出错: {e}") diff --git a/update_harmony_icons.py b/update_harmony_icons.py new file mode 100644 index 0000000..7879fe2 --- /dev/null +++ b/update_harmony_icons.py @@ -0,0 +1,48 @@ +from PIL import Image +import os + +# 新的图片路径 +new_image_path = r"e:\project\flutter\f3\flutter_application_2\assets\IMG_20260402_172628.png" + +# 输出目录 +app_scope_dir = r"e:\project\flutter\f3\flutter_application_2\ohos\AppScope\resources\base\media" +entry_media_dir = r"e:\project\flutter\f3\flutter_application_2\ohos\entry\src\main\resources\base\media" + +try: + # 打开新图片 + with Image.open(new_image_path) as img: + print(f"新图片尺寸: {img.size}") + + # 调整为 288x288 用于 app_icon.png + img_288 = img.resize((288, 288), Image.Resampling.LANCZOS) + app_icon_path = os.path.join(app_scope_dir, "app_icon.png") + img_288.save(app_icon_path) + print(f"已保存 288x288 图标到: {app_icon_path}") + + # 调整为 1024x1024 用于 entry 目录的图标 + img_1024 = img.resize((1024, 1024), Image.Resampling.LANCZOS) + + # 保存到 entry 目录 + entry_icon_path = os.path.join(entry_media_dir, "icon.png") + img_1024.save(entry_icon_path) + print(f"已保存 1024x1024 图标到: {entry_icon_path}") + + # 保存其他尺寸 + sizes = [ + (216, "icon_216.png"), + (48, "icon_48.png"), + (512, "icon_512.png"), + (72, "icon_72.png"), + (96, "icon_96.png"), + ] + + for size, filename in sizes: + resized_img = img.resize((size, size), Image.Resampling.LANCZOS) + output_path = os.path.join(entry_media_dir, filename) + resized_img.save(output_path) + print(f"已保存 {size}x{size} 图标到: {output_path}") + + print("\n鸿蒙端所有图标更新完成!") + +except Exception as e: + print(f"处理图片时出错: {e}")