From c897f508176fbc5c913ca779da76f7b43ebb83a9 Mon Sep 17 00:00:00 2001 From: Developer Date: Tue, 31 Mar 2026 20:15:16 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=86=E8=8A=82=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/views/active/active_search_page.dart | 169 ++--- lib/views/home/home_part.dart | 77 ++- lib/views/profile/per_card.dart | 762 +++++++++++++---------- lib/views/profile/profile_page.dart | 161 +++-- lib/views/profile/settings/app_fun.dart | 58 +- 5 files changed, 725 insertions(+), 502 deletions(-) diff --git a/lib/views/active/active_search_page.dart b/lib/views/active/active_search_page.dart index 5bdad0c..499e536 100644 --- a/lib/views/active/active_search_page.dart +++ b/lib/views/active/active_search_page.dart @@ -117,88 +117,90 @@ class _ActiveSearchPageState extends State children: [ // 自定义标题栏 if (isInTabBarView) - Container( - height: 56, - padding: const EdgeInsets.symmetric(horizontal: 16), - color: Colors.white, - child: Row( - children: [ - // 返回按钮 - //todo - IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.black87), - onPressed: () { - // 检查是否可以返回,避免黑屏 - if (Navigator.of(context).canPop()) { - Navigator.of(context).pop(); - } else { - // 如果无法返回(如在 TabBarView 中),跳转到主页 - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (_) => const MainNavigation(), - ), - ); - } - }, - tooltip: '返回上一页', - ), - // 标题 - Expanded( - child: Row( - children: [ - const Icon( - Icons.travel_explore, - size: 20, - color: Colors.black87, - ), - const SizedBox(width: 8), - const Text( - '诗词搜索', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w600, + SafeArea( + child: Container( + height: 56, + padding: const EdgeInsets.symmetric(horizontal: 16), + color: Colors.white, + child: Row( + children: [ + // 返回按钮 + //todo + IconButton( + icon: const Icon(Icons.arrow_back, color: Colors.black87), + onPressed: () { + // 检查是否可以返回,避免黑屏 + if (Navigator.of(context).canPop()) { + Navigator.of(context).pop(); + } else { + // 如果无法返回(如在 TabBarView 中),跳转到主页 + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (_) => const MainNavigation(), + ), + ); + } + }, + tooltip: '返回上一页', + ), + // 标题 + Expanded( + child: Row( + children: [ + const Icon( + Icons.travel_explore, + size: 20, color: Colors.black87, ), - ), - ], - ), - ), - // 更多按钮 - IconButton( - icon: const Icon(Icons.more_vert, color: Colors.black87), - onPressed: () { - // 更多按钮的点击事件 - showModalBottomSheet( - context: context, - builder: (context) => Container( - padding: const EdgeInsets.all(16), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ListTile( - leading: const Icon(Icons.history), - title: const Text('搜索历史'), - onTap: () { - Navigator.pop(context); - // 实现搜索历史功能 - }, - ), - ListTile( - leading: const Icon(Icons.settings), - title: const Text('搜索设置'), - onTap: () { - Navigator.pop(context); - // 实现搜索设置功能 - }, - ), - ], + const SizedBox(width: 8), + const Text( + '诗词搜索', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + color: Colors.black87, + ), ), - ), - ); - }, - tooltip: '更多', - ), - ], + ], + ), + ), + // 更多按钮 + IconButton( + icon: const Icon(Icons.more_vert, color: Colors.black87), + onPressed: () { + // 更多按钮的点击事件 + showModalBottomSheet( + context: context, + builder: (context) => Container( + padding: const EdgeInsets.all(16), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + leading: const Icon(Icons.history), + title: const Text('搜索历史(开发中)'), + onTap: () { + Navigator.pop(context); + // 实现搜索历史功能 + }, + ), + ListTile( + leading: const Icon(Icons.settings), + title: const Text('搜索设置(开发中)'), + onTap: () { + Navigator.pop(context); + // 实现搜索设置功能 + }, + ), + ], + ), + ), + ); + }, + tooltip: '更多', + ), + ], + ), ), ), // 搜索内容区域 @@ -209,9 +211,9 @@ class _ActiveSearchPageState extends State Padding( padding: EdgeInsets.fromLTRB( AppConstants.pageHorizontalPadding, - isInTabBarView ? 16 : 8, + isInTabBarView ? 8 : 4, AppConstants.pageHorizontalPadding, - 8, + 4, ), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, @@ -256,10 +258,9 @@ class _ActiveSearchPageState extends State onChanged: (_) => setState(() {}), ), ), - const SizedBox(height: 8), Wrap( - spacing: 8, - runSpacing: 8, + spacing: 4, + runSpacing: 4, crossAxisAlignment: WrapCrossAlignment.center, children: [ const Text('', style: TextStyle(fontSize: 13)), diff --git a/lib/views/home/home_part.dart b/lib/views/home/home_part.dart index 0852b08..9ea3a64 100644 --- a/lib/views/home/home_part.dart +++ b/lib/views/home/home_part.dart @@ -141,8 +141,38 @@ class _PoetryCardState extends State { _buildTitleSection(), if (widget.poetryData.drtime.isNotEmpty) ...[ _buildContentSection(context), - const SizedBox(height: 16), + const SizedBox(height: 3), ], + // 精选诗句标签 - 放在缝隙位置 + Align( + alignment: Alignment.centerRight, + child: Container( + margin: EdgeInsets.zero, + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 2, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '精选诗句', + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w500, + color: AppConstants.primaryColor, + ), + ), + const SizedBox(width: 4), + Icon( + Icons.format_quote, + color: AppConstants.primaryColor, + size: 14, + ), + ], + ), + ), + ), _buildNameSection(), const SizedBox(height: 12), if (widget.keywordList.isNotEmpty) ...[ @@ -333,7 +363,7 @@ class _PoetryCardState extends State { return Container( width: double.infinity, padding: const EdgeInsets.all(16), - margin: const EdgeInsets.only(bottom: 8), + margin: EdgeInsets.zero, decoration: BoxDecoration( gradient: LinearGradient( colors: [ @@ -359,27 +389,6 @@ class _PoetryCardState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Icon( - Icons.format_quote, - color: AppConstants.primaryColor, - size: 20, - ), - const SizedBox(width: 8), - Expanded( - child: Text( - '精选诗句', - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.w500, - color: AppConstants.primaryColor, - ), - ), - ), - ], - ), - const SizedBox(height: 8), GestureDetector( onLongPress: () => CopyUtils.showCopyDialog(context, widget.poetryData.name, '诗词'), @@ -409,7 +418,7 @@ class _PoetryCardState extends State { ), ) : Text( - widget.poetryData.name, + _formatPoetryText(widget.poetryData.name), style: const TextStyle( fontSize: 22, fontWeight: FontWeight.bold, @@ -424,6 +433,22 @@ class _PoetryCardState extends State { ); } + String _formatPoetryText(String text) { + // 检查文本长度(文字+符号) + if (text.length < 10) { + return text; // 小于10个字,不换行 + } + + // 找到第一个逗号的位置 + final commaIndex = text.indexOf(','); + if (commaIndex != -1) { + // 在第一个逗号处添加换行 + return text.replaceFirst(',', ',\n'); + } + + return text; // 没有逗号,保持原样 + } + Widget _buildKeywordSection() { final isLoading = widget.sectionLoadingStates?['keywords'] ?? false; @@ -441,7 +466,7 @@ class _PoetryCardState extends State { children: [ SizedBox( width: 16, - height: 16, + height: 8, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation( @@ -449,7 +474,7 @@ class _PoetryCardState extends State { ), ), ), - const SizedBox(width: 8), + const SizedBox(width: 4), Text( '关键词加载中...', style: TextStyle( diff --git a/lib/views/profile/per_card.dart b/lib/views/profile/per_card.dart index 7ae6dd5..89ce7df 100644 --- a/lib/views/profile/per_card.dart +++ b/lib/views/profile/per_card.dart @@ -7,10 +7,10 @@ import '../../constants/app_constants.dart'; import '../../services/network_listener_service.dart'; import 'guide/tongji.dart'; -/// 时间: 2026-03-25 +/// 时间: 2026-03-31 /// 功能: 个人信息卡片组件 /// 介绍: 可收起/张开的个人信息卡片,支持下拉张开,上滑收起 -/// 最新变化: 优化动画效果,添加毛玻璃背景,修复布局问题 +/// 最新变化: 重新设计为苹果风格,优化动画效果,改进布局结构,提升用户体验 class PersonalCard extends StatefulWidget { final Map userData; @@ -18,14 +18,16 @@ class PersonalCard extends StatefulWidget { final ValueChanged? onExpandChanged; final int currentPage; final ValueChanged? onPageChanged; + final VoidCallback? onAvatarTap; const PersonalCard({ super.key, required this.userData, this.isExpanded, this.onExpandChanged, - this.currentPage = 1, + this.currentPage = 0, this.onPageChanged, + this.onAvatarTap, }); @override @@ -36,6 +38,8 @@ class PersonalCardState extends State { late bool _isExpanded; late String _currentTip; bool _isOnline = true; + bool _isEditingNickname = false; + late TextEditingController _nicknameController; // 累计数据 int _totalViews = 0; @@ -47,10 +51,19 @@ class PersonalCardState extends State { super.initState(); _isExpanded = widget.isExpanded ?? false; _currentTip = _getRandomTip(); + _nicknameController = TextEditingController( + text: widget.userData['nickname'] ?? '诗词爱好者', + ); _loadOnlineStatus(); _loadTotalStats(); } + @override + void dispose() { + _nicknameController.dispose(); + super.dispose(); + } + Future _loadTotalStats() async { final views = await StatisticsManager().getTotalViews(); final likes = await StatisticsManager().getTotalLikes(); @@ -213,37 +226,54 @@ class PersonalCardState extends State { @override Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.translucent, - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - AppConstants.primaryColor.withValues(alpha: 0.95), - AppConstants.primaryColor.withValues(alpha: 0.9), - AppConstants.primaryColor.withValues(alpha: 0.85), - ], - begin: Alignment.topCenter, - end: Alignment.bottomCenter, + return Container( + margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 10, + offset: const Offset(0, 2), ), - ), - child: AnimatedContainer( - duration: const Duration(milliseconds: 400), - curve: Curves.easeInOut, - padding: _isExpanded - ? const EdgeInsets.all(16) - : const EdgeInsets.symmetric(horizontal: 20, vertical: 12), - height: _isExpanded ? null : 72, - child: Stack( - children: [ - // 毛玻璃效果层(在文字按钮下层,背景色上层) - BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), - child: Container(color: Colors.transparent), + ], + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(20), + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + AppConstants.primaryColor.withOpacity(0.95), + AppConstants.primaryColor.withOpacity(0.85), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + child: GestureDetector( + onTap: _toggleExpand, + behavior: HitTestBehavior.opaque, + child: AnimatedContainer( + duration: AppConstants.animationDurationMedium, + curve: Curves.easeOut, + padding: _isExpanded + ? const EdgeInsets.all(20) + : const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Stack( + children: [ + // 毛玻璃效果层 + BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), + child: Container(color: Colors.transparent), + ), + // 内容层 + _isExpanded + ? _buildExpandedContent() + : _buildCollapsedContent(), + ], ), - // 内容层(在毛玻璃效果上层) - _isExpanded ? _buildExpandedContent() : _buildCollapsedContent(), - ], + ), ), ), ), @@ -253,105 +283,168 @@ class PersonalCardState extends State { Widget _buildCollapsedContent() { return Row( children: [ - // 左侧区域:可点击展开/收起 - Expanded( - child: GestureDetector( - onTap: _toggleExpand, - child: Row( - children: [ - // 头像在左边 - AnimatedContainer( - duration: const Duration(milliseconds: 400), - curve: Curves.easeInOut, - child: Stack( - children: [ - CircleAvatar( - radius: 24, - backgroundColor: Colors.white, - child: Text( - widget.userData['avatar'] ?? '👤', - style: const TextStyle(fontSize: 18), - ), - ), - Positioned( - bottom: 0, - right: 0, - child: Container( - width: 16, - height: 16, - decoration: BoxDecoration( - color: _isOnline - ? AppConstants.successColor - : Colors.red, - border: Border.all(color: Colors.white, width: 2), - borderRadius: BorderRadius.circular(8), - ), - child: Icon( - _isOnline ? Icons.check : Icons.close, - color: Colors.white, - size: 10, - ), - ), - ), - ], - ), - ), - const SizedBox(width: 12), - // 名称和签名 - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - widget.userData['nickname'] ?? '诗词爱好者', - style: const TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - overflow: TextOverflow.ellipsis, - ), - const SizedBox(height: 4), - Text( - widget.userData['signature'] ?? '人生如诗,岁月如歌', - style: const TextStyle( - color: Colors.white70, - fontSize: 12, - ), - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - ], - ), - ), - ), - const SizedBox(width: 12), - // 右侧区域:标签栏,不可触发展开/收起 + // 头像 GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () {}, - child: Row( + onTap: widget.onAvatarTap, + child: Stack( children: [ - _buildTabLabel(0, '卡片'), - _buildTabLabel(1, '设置'), - _buildTabLabel(2, '更多'), + Container( + width: 48, + height: 48, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 4, + offset: const Offset(0, 2), + ), + ], + ), + child: Center( + child: Text( + widget.userData['avatar'] ?? '👤', + style: const TextStyle(fontSize: 32), + ), + ), + ), + // 在线状态指示器 + Positioned( + bottom: 0, + right: 0, + child: Container( + width: 16, + height: 16, + decoration: BoxDecoration( + color: _isOnline ? AppConstants.successColor : Colors.red, + border: Border.all(color: Colors.white, width: 2), + borderRadius: BorderRadius.circular(8), + ), + ), + ), ], ), ), + const SizedBox(width: 16), + // 名称和签名 + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + widget.userData['nickname'] ?? '诗词爱好者', + style: const TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 4), + Text( + widget.userData['signature'] ?? '人生如诗,岁月如歌', + style: const TextStyle(color: Colors.white70, fontSize: 14), + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + // 页面切换提示 + Row( + children: [ + // 选项提示 + Container( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Row( + children: [ + _buildCollapsedTabLabel(0, '卡片'), + const SizedBox(width: 12), + _buildCollapsedTabLabel(1, '设置'), + const SizedBox(width: 12), + _buildCollapsedTabLabel(2, '更多'), + ], + ), + ), + // 滑动指示箭头 + Container( + padding: const EdgeInsets.all(8), + child: Row( + children: [ + AnimatedRotation( + turns: _isExpanded ? 0.5 : 0, + duration: AppConstants.animationDurationMedium, + child: const Icon( + Icons.keyboard_arrow_down, + color: Colors.white, + size: 20, + ), + ), + const SizedBox(width: 4), + const Icon(Icons.swap_horiz, color: Colors.white70, size: 16), + ], + ), + ), + ], + ), ], ); } Widget _buildExpandedContent() { return Column( - mainAxisSize: MainAxisSize.min, children: [ + // 头部信息 Row( children: [ + // 头像 + GestureDetector( + onTap: widget.onAvatarTap, + child: Stack( + children: [ + Container( + width: 64, + height: 64, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 6, + offset: const Offset(0, 3), + ), + ], + ), + child: Center( + child: Text( + widget.userData['avatar'] ?? '👤', + style: const TextStyle(fontSize: 40), + ), + ), + ), + // 在线状态指示器 + Positioned( + bottom: 2, + right: 2, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration( + color: _isOnline + ? AppConstants.successColor + : Colors.red, + border: Border.all(color: Colors.white, width: 2), + borderRadius: BorderRadius.circular(10), + ), + ), + ), + ], + ), + ), + const SizedBox(width: 16), + // 个人信息 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -359,29 +452,84 @@ class PersonalCardState extends State { // 昵称和等级 Row( children: [ - Text( - widget.userData['nickname'] ?? '诗词爱好者', - style: const TextStyle( - color: Colors.white, - fontSize: 16, - fontWeight: FontWeight.bold, + Expanded( + child: _isEditingNickname + ? TextField( + controller: _nicknameController, + style: const TextStyle( + color: AppConstants.primaryColor, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + decoration: const InputDecoration( + border: InputBorder.none, + focusedBorder: InputBorder.none, + enabledBorder: InputBorder.none, + hintText: '输入昵称', + hintStyle: TextStyle( + color: AppConstants.primaryColor, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + onSubmitted: (value) { + setState(() { + widget.userData['nickname'] = value; + _isEditingNickname = false; + }); + }, + ) + : GestureDetector( + onTap: () { + setState(() { + _isEditingNickname = true; + _nicknameController.text = + widget.userData['nickname'] ?? '诗词爱好者'; + }); + }, + child: Text( + widget.userData['nickname'] ?? '诗词爱好者', + style: const TextStyle( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.bold, + decoration: TextDecoration.underline, + ), + ), + ), + ), + const SizedBox(width: 8), + GestureDetector( + onTap: () { + setState(() { + _isEditingNickname = !_isEditingNickname; + if (_isEditingNickname) { + _nicknameController.text = + widget.userData['nickname'] ?? '诗词爱好者'; + } + }); + }, + child: Icon( + _isEditingNickname ? Icons.check : Icons.edit, + color: Colors.white70, + size: 18, ), ), - const SizedBox(width: 6), + const SizedBox(width: 8), Container( padding: const EdgeInsets.symmetric( - horizontal: 6, + horizontal: 8, vertical: 2, ), decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.2), - borderRadius: BorderRadius.circular(10), + color: Colors.white.withOpacity(0.2), + borderRadius: BorderRadius.circular(12), ), child: Text( widget.userData['level'] ?? 'Lv.1', style: const TextStyle( color: Colors.white, - fontSize: 10, + fontSize: 12, fontWeight: FontWeight.w500, ), ), @@ -394,200 +542,139 @@ class PersonalCardState extends State { widget.userData['signature'] ?? '人生如诗,岁月如歌', style: const TextStyle( color: Colors.white70, - fontSize: 12, - height: 1.2, + fontSize: 14, + height: 1.3, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), - const SizedBox(height: 10), - // 累计统计卡片 - Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 10, - ), - decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.15), - borderRadius: BorderRadius.circular(12), - ), - child: Column( - children: [ - Text( - '累计', - style: const TextStyle( - color: Colors.white70, - fontSize: 11, - ), - ), - const SizedBox(height: 8), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - _buildStatItem('浏览', _totalViews), - const SizedBox(width: 16), - _buildStatItem('点赞', _totalLikes), - const SizedBox(width: 16), - _buildStatItem('答题', _totalQuestions), - ], - ), - ], - ), - ), ], ), ), - const SizedBox(width: 10), - // 头像在右边 - AnimatedContainer( - duration: const Duration(milliseconds: 400), - curve: Curves.easeInOut, - child: Stack( + ], + ), + const SizedBox(height: 10), + // 统计数据卡片 + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.1), + borderRadius: BorderRadius.circular(16), + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - CircleAvatar( - radius: 36, - backgroundColor: Colors.white, - child: Text( - widget.userData['avatar'] ?? '👤', - style: const TextStyle(fontSize: 20), - ), + _buildStatItem('浏览', _totalViews), + Container( + width: 1, + height: 40, + color: Colors.white.withOpacity(0.2), ), - Positioned( - bottom: 0, - right: 0, - child: Container( - width: 18, - height: 18, - decoration: BoxDecoration( - color: _isOnline - ? AppConstants.successColor - : Colors.red, - border: Border.all(color: Colors.white, width: 2), - borderRadius: BorderRadius.circular(9), - ), - child: Icon( - _isOnline ? Icons.check : Icons.close, - color: Colors.white, - size: 10, - ), - ), + _buildStatItem('点赞', _totalLikes), + Container( + width: 1, + height: 40, + color: Colors.white.withOpacity(0.2), ), + _buildStatItem('答题', _totalQuestions), ], ), + ], + ), + ), + const SizedBox(height: 8), + // 祝福语卡片 + GestureDetector( + onTap: () { + HapticFeedback.lightImpact(); + _showRandomTip(); + }, + child: Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.1), + blurRadius: 4, + offset: const Offset(0, 2), + ), + ], ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + '💡 $_currentTip', + style: const TextStyle( + color: AppConstants.primaryColor, + fontSize: 14, + fontWeight: FontWeight.w600, + height: 1.3, + ), + maxLines: 2, + ), + ), + const SizedBox(width: 12), + // 在线状态开关 + Switch( + value: _isOnline, + onChanged: (value) { + _toggleOnlineStatus(); + }, + activeColor: AppConstants.primaryColor, + inactiveTrackColor: Colors.grey.shade300, + inactiveThumbColor: Colors.grey, + ), + ], + ), + ), + ), + const SizedBox(height: 16), + // 页面标签 + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildTabLabel(0, '卡片', Icons.credit_card), + const SizedBox(width: 32), + _buildTabLabel(1, '设置', Icons.settings), + const SizedBox(width: 32), + _buildTabLabel(2, '更多', Icons.more_horiz), ], ), const SizedBox(height: 8), - // 操作按钮 - 文本祝福语 - Row( - children: [ - Expanded( - child: GestureDetector( - onTap: () { - HapticFeedback.lightImpact(); - _showRandomTip(); - }, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 12, - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.1), - blurRadius: 4, - offset: const Offset(0, 2), - ), - ], - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - '💡:$_currentTip', - style: const TextStyle( - color: AppConstants.primaryColor, - fontSize: 14, - fontWeight: FontWeight.w600, - ), - textAlign: TextAlign.left, - maxLines: 3, - ), - ), - const SizedBox(width: 12), - // 在线状态开关 - Switch( - value: _isOnline, - onChanged: (value) { - _toggleOnlineStatus(); - }, - activeColor: AppConstants.primaryColor, - inactiveTrackColor: Colors.grey.shade300, - inactiveThumbColor: Colors.grey, - ), - ], - ), + // 页面指示器 + Container( + height: 3, + margin: const EdgeInsets.symmetric(horizontal: 40), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.2), + borderRadius: BorderRadius.circular(1.5), + ), + child: Stack( + children: [ + AnimatedContainer( + duration: AppConstants.animationDurationMedium, + curve: Curves.easeOut, + width: (MediaQuery.of(context).size.width - 160) / 3, + height: 3, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(1.5), + ), + margin: EdgeInsets.only( + left: + ((MediaQuery.of(context).size.width - 160) / 3) * + widget.currentPage, ), ), - ), - ], - ), - // 标签栏 - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () {}, - child: Container( - padding: const EdgeInsets.symmetric(vertical: 4), - child: Row( - children: [ - // 页面指示器 - Expanded( - child: Container( - height: 3, - margin: const EdgeInsets.symmetric(horizontal: 20), - decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.3), - borderRadius: BorderRadius.circular(2), - ), - child: Stack( - children: [ - // 背景条 - Container( - height: 3, - decoration: BoxDecoration( - color: Colors.white.withValues(alpha: 0.3), - borderRadius: BorderRadius.circular(2), - ), - ), - // 滑动指示器 - AnimatedContainer( - duration: const Duration(milliseconds: 300), - width: MediaQuery.of(context).size.width / 3 - 40, - height: 3, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(2), - ), - margin: EdgeInsets.only( - left: - (MediaQuery.of(context).size.width / 3 - 40) * - widget.currentPage, - ), - ), - ], - ), - ), - ), - // 页面标签 - _buildTabLabel(0, '卡片'), - _buildTabLabel(1, '设置'), - _buildTabLabel(2, '更多'), - ], - ), + ], ), ), ], @@ -601,7 +688,7 @@ class PersonalCardState extends State { value.toString(), style: const TextStyle( color: Colors.white, - fontSize: 16, + fontSize: 18, fontWeight: FontWeight.bold, ), ), @@ -614,8 +701,34 @@ class PersonalCardState extends State { ); } - Widget _buildTabLabel(int index, String label) { - // === 单个页面标签:可点击切换到对应页面 === + Widget _buildTabLabel(int index, String label, IconData icon) { + final isSelected = widget.currentPage == index; + return GestureDetector( + onTap: () { + widget.onPageChanged?.call(index); + }, + child: Column( + children: [ + Icon( + icon, + color: isSelected ? Colors.white : Colors.white70, + size: 20, + ), + const SizedBox(height: 4), + Text( + label, + style: TextStyle( + color: isSelected ? Colors.white : Colors.white70, + fontSize: 12, + fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, + ), + ), + ], + ), + ); + } + + Widget _buildCollapsedTabLabel(int index, String label) { final isSelected = widget.currentPage == index; return GestureDetector( onTap: () { @@ -623,28 +736,19 @@ class PersonalCardState extends State { }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - index == 0 - ? Icons.credit_card - : index == 1 - ? Icons.settings - : Icons.more_horiz, - color: isSelected ? Colors.white : Colors.white70, - size: 16, - ), - const SizedBox(height: 2), - Text( - label, - style: TextStyle( - color: isSelected ? Colors.white : Colors.white70, - fontSize: 10, - fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, - ), - ), - ], + decoration: BoxDecoration( + color: isSelected + ? Colors.white.withOpacity(0.2) + : Colors.transparent, + borderRadius: BorderRadius.circular(12), + ), + child: Text( + label, + style: TextStyle( + color: isSelected ? Colors.white : Colors.white70, + fontSize: 12, + fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, + ), ), ), ); diff --git a/lib/views/profile/profile_page.dart b/lib/views/profile/profile_page.dart index 17de39d..ee2ad98 100644 --- a/lib/views/profile/profile_page.dart +++ b/lib/views/profile/profile_page.dart @@ -4,6 +4,7 @@ /// 最新变化: 重新设计布局,实现朋友圈风格的个人页面 import 'dart:convert'; +import 'dart:math' show Random; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -66,6 +67,30 @@ class _ProfilePageState extends State int _todayQuestions = 0; int _todayLikes = 0; + // 可爱的emoji列表 + final List _avatars = [ + '👤', + '😊', + '🎉', + '🌟', + '🔥', + '💎', + '🌈', + '🦋', + '🌸', + '🐱', + '🐶', + '🐼', + '🐨', + '🐵', + '🦄', + '🐸', + '🐹', + '🐰', + '🦊', + '🐻', + ]; + // 模拟用户数据 final Map _userData = { 'avatar': '👤', // 使用emoji代替网络图片 @@ -81,6 +106,14 @@ class _ProfilePageState extends State 'views': 3560, }; + // 更换头像 + void _changeAvatar() { + final random = Random(); + setState(() { + _userData['avatar'] = _avatars[random.nextInt(_avatars.length)]; + }); + } + @override void initState() { super.initState(); @@ -307,6 +340,7 @@ class _ProfilePageState extends State ); } }, + onAvatarTap: _changeAvatar, ); } @@ -395,43 +429,43 @@ class _ProfilePageState extends State ), const SizedBox(height: 16), // === 互动统计卡片 === - if (!_isStatsHidden) - Container( - width: double.infinity, - padding: const EdgeInsets.all(20), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), - boxShadow: [ - BoxShadow( - color: Colors.black.withValues(alpha: 0.08), - blurRadius: 10, - offset: const Offset(0, 2), - ), - ], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Icon( - Icons.analytics_outlined, + Container( + width: double.infinity, + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.08), + blurRadius: 10, + offset: const Offset(0, 2), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.analytics_outlined, + color: AppConstants.primaryColor, + size: 20, + ), + const SizedBox(width: 8), + Text( + '诗词挑战', + style: TextStyle( color: AppConstants.primaryColor, - size: 20, + fontSize: 16, + fontWeight: FontWeight.bold, ), - const SizedBox(width: 8), - Text( - '诗词挑战', - style: TextStyle( - color: AppConstants.primaryColor, - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - const SizedBox(height: 16), + ), + ], + ), + const SizedBox(height: 16), + if (!_isStatsHidden) Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ @@ -439,35 +473,42 @@ class _ProfilePageState extends State _buildInteractionItem('本周答题', '$_weekQuestions'), _buildInteractionItem('答对次数', '$_correctAnswers'), ], - ), - const SizedBox(height: 16), - SizedBox( - width: double.infinity, - child: ElevatedButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (_) => const PoetryLevelPage(), - ), - ); - }, - style: ElevatedButton.styleFrom( - backgroundColor: AppConstants.primaryColor, - padding: const EdgeInsets.symmetric(vertical: 12), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - child: const Text( - '开始诗词答题', - style: TextStyle(fontSize: 16), + ) + else + Center( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: Text( + '数据已隐藏', + style: TextStyle(color: Colors.grey[500], fontSize: 14), ), ), ), - ], - ), + const SizedBox(height: 16), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => const PoetryLevelPage(), + ), + ); + }, + style: ElevatedButton.styleFrom( + backgroundColor: AppConstants.primaryColor, + padding: const EdgeInsets.symmetric(vertical: 12), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + ), + child: const Text('开始诗词答题', style: TextStyle(fontSize: 16)), + ), + ), + ], ), + ), ], ), ); diff --git a/lib/views/profile/settings/app_fun.dart b/lib/views/profile/settings/app_fun.dart index aeaaebc..280c0cc 100644 --- a/lib/views/profile/settings/app_fun.dart +++ b/lib/views/profile/settings/app_fun.dart @@ -371,9 +371,61 @@ class _AppFunSettingsPageState extends State { ), trailing: Icon(Icons.chevron_right, color: Colors.grey[400]), onTap: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => const WidgetsPage()), + // 显示对话框提示鸿蒙设备设置方法 + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Row( + children: [ + Icon(Icons.info_outline, color: AppConstants.primaryColor), + const SizedBox(width: 8), + const Text('桌面卡片设置'), + ], + ), + content: const Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '鸿蒙设备请在桌面端设置:', + style: TextStyle(fontWeight: FontWeight.bold), + ), + SizedBox(height: 8), + Text('1. 长按桌面空白处'), + Text('2. 选择「情景诗词」卡片'), + Text('3. 添加后点击桌面卡片即可设置'), + SizedBox(height: 12), + Text( + '注意:该页面设置对鸿蒙设备不生效', + style: TextStyle(color: Colors.orange, fontSize: 12), + ), + ], + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('取消'), + ), + ElevatedButton( + onPressed: () { + Navigator.of(context).pop(); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const WidgetsPage(), + ), + ); + }, + style: ElevatedButton.styleFrom( + backgroundColor: AppConstants.primaryColor, + foregroundColor: Colors.white, + ), + child: const Text('仍要进入'), + ), + ], + ); + }, ); }, );