From 5bacd21840ac2588aec984d0fa3d7f0c3ca89efb Mon Sep 17 00:00:00 2001 From: hailin Date: Thu, 5 Feb 2026 21:50:43 -0800 Subject: [PATCH] =?UTF-8?q?feat(mobile-app):=20=E4=B8=BA3=E4=B8=AA?= =?UTF-8?q?=E4=B8=BB=E5=AF=BC=E8=88=AA=E9=A1=B5=E9=9D=A2=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E5=88=B7=E6=96=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - TradingPage (兑换): 添加 RefreshIndicator,刷新时重新加载钱包和收益数据 - RankingPage (龙虎榜): 添加 RefreshIndicator,刷新时 invalidate leaderboardStatusProvider - 列表视图和待开启状态视图均支持下拉刷新 - MiningPage (监控): 使用 LayoutBuilder + IntrinsicHeight 模式实现 - 刷新时并行加载用户数据、授权数据和钱包状态 注:ProfilePage 已有完整的下拉刷新实现,无需修改 Co-Authored-By: Claude Opus 4.5 --- .../presentation/pages/mining_page.dart | 51 +++++-- .../presentation/pages/ranking_page.dart | 124 +++++++++++------- .../presentation/pages/trading_page.dart | 16 ++- 3 files changed, 129 insertions(+), 62 deletions(-) diff --git a/frontend/mobile-app/lib/features/mining/presentation/pages/mining_page.dart b/frontend/mobile-app/lib/features/mining/presentation/pages/mining_page.dart index e82e81c1..61a77764 100644 --- a/frontend/mobile-app/lib/features/mining/presentation/pages/mining_page.dart +++ b/frontend/mobile-app/lib/features/mining/presentation/pages/mining_page.dart @@ -224,6 +224,16 @@ class _MiningPageState extends ConsumerState { ); } + /// 下拉刷新 + Future _onRefresh() async { + debugPrint('[MiningPage] 下拉刷新'); + await Future.wait([ + _loadUserData(), + _loadAuthorizationData(), + _checkWalletStatus(), + ]); + } + /// 开启监控 void _startMonitor() { setState(() { @@ -268,18 +278,35 @@ class _MiningPageState extends ConsumerState { ), ), child: SafeArea( - child: Column( - children: [ - // 顶部标题栏 - _buildAppBar(), - // 用户信息区域 - _buildUserInfo(), - const SizedBox(height: 24), - // 挖矿状态区域 - Expanded( - child: _buildMiningStatusArea(), - ), - ], + child: RefreshIndicator( + onRefresh: _onRefresh, + color: const Color(0xFFD4AF37), + backgroundColor: Colors.white, + child: LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: ConstrainedBox( + constraints: BoxConstraints(minHeight: constraints.maxHeight), + child: IntrinsicHeight( + child: Column( + children: [ + // 顶部标题栏 + _buildAppBar(), + // 用户信息区域 + _buildUserInfo(), + const SizedBox(height: 24), + // 挖矿状态区域 + Expanded( + child: _buildMiningStatusArea(), + ), + ], + ), + ), + ), + ); + }, + ), ), ), ), diff --git a/frontend/mobile-app/lib/features/ranking/presentation/pages/ranking_page.dart b/frontend/mobile-app/lib/features/ranking/presentation/pages/ranking_page.dart index ee3d46ae..a2e30081 100644 --- a/frontend/mobile-app/lib/features/ranking/presentation/pages/ranking_page.dart +++ b/frontend/mobile-app/lib/features/ranking/presentation/pages/ranking_page.dart @@ -88,6 +88,13 @@ class _RankingPageState extends ConsumerState { ), ]; + /// 下拉刷新 + Future _onRefresh() async { + debugPrint('[RankingPage] 下拉刷新'); + ref.invalidate(leaderboardStatusProvider); + // TODO: 未来对接真实排行榜数据时,在此处 invalidate 排行榜数据 Provider + } + /// 切换排行榜类型 void _selectRankingType(RankingType type) { setState(() { @@ -198,46 +205,61 @@ class _RankingPageState extends ConsumerState { break; } - return Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - // 图标 - Container( - width: 80, - height: 80, - decoration: BoxDecoration( - color: const Color(0x1A8B5A2B), - borderRadius: BorderRadius.circular(40), + return RefreshIndicator( + onRefresh: _onRefresh, + color: const Color(0xFFD4AF37), + backgroundColor: Colors.white, + child: LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: ConstrainedBox( + constraints: BoxConstraints(minHeight: constraints.maxHeight), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // 图标 + Container( + width: 80, + height: 80, + decoration: BoxDecoration( + color: const Color(0x1A8B5A2B), + borderRadius: BorderRadius.circular(40), + ), + child: const Icon( + Icons.hourglass_empty, + size: 40, + color: Color(0xFF8B5A2B), + ), + ), + const SizedBox(height: 24), + // 标题 + Text( + '$boardName待开启', + style: const TextStyle( + fontSize: 18, + fontFamily: 'Inter', + fontWeight: FontWeight.w700, + color: Color(0xFF5D4037), + ), + ), + const SizedBox(height: 8), + // 描述 + const Text( + '该榜单暂未开启,请稍后再来', + style: TextStyle( + fontSize: 14, + fontFamily: 'Inter', + color: Color(0xFF8B5A2B), + ), + ), + ], + ), + ), ), - child: const Icon( - Icons.hourglass_empty, - size: 40, - color: Color(0xFF8B5A2B), - ), - ), - const SizedBox(height: 24), - // 标题 - Text( - '$boardName待开启', - style: const TextStyle( - fontSize: 18, - fontFamily: 'Inter', - fontWeight: FontWeight.w700, - color: Color(0xFF5D4037), - ), - ), - const SizedBox(height: 8), - // 描述 - const Text( - '该榜单暂未开启,请稍后再来', - style: TextStyle( - fontSize: 14, - fontFamily: 'Inter', - color: Color(0xFF8B5A2B), - ), - ), - ], + ); + }, ), ); } @@ -461,15 +483,21 @@ class _RankingPageState extends ConsumerState { /// 构建排行榜列表 Widget _buildRankingList() { - return ListView.builder( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - itemCount: _mockRankingData.length, - itemBuilder: (context, index) { - return Padding( - padding: const EdgeInsets.only(bottom: 4), - child: _buildRankingItem(_mockRankingData[index]), - ); - }, + return RefreshIndicator( + onRefresh: _onRefresh, + color: const Color(0xFFD4AF37), + backgroundColor: Colors.white, + child: ListView.builder( + physics: const AlwaysScrollableScrollPhysics(), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + itemCount: _mockRankingData.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.only(bottom: 4), + child: _buildRankingItem(_mockRankingData[index]), + ); + }, + ), ); } diff --git a/frontend/mobile-app/lib/features/trading/presentation/pages/trading_page.dart b/frontend/mobile-app/lib/features/trading/presentation/pages/trading_page.dart index 111ed8c5..9a273a26 100644 --- a/frontend/mobile-app/lib/features/trading/presentation/pages/trading_page.dart +++ b/frontend/mobile-app/lib/features/trading/presentation/pages/trading_page.dart @@ -218,6 +218,12 @@ class _TradingPageState extends ConsumerState { } } + /// 下拉刷新 + Future _onRefresh() async { + debugPrint('[TradingPage] 下拉刷新'); + await _loadWalletData(); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -236,8 +242,13 @@ class _TradingPageState extends ConsumerState { ), ), child: SafeArea( - child: SingleChildScrollView( - child: Column( + child: RefreshIndicator( + onRefresh: _onRefresh, + color: const Color(0xFFD4AF37), + backgroundColor: Colors.white, + child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: Column( children: [ // 顶部标题栏 _buildAppBar(), @@ -273,6 +284,7 @@ class _TradingPageState extends ConsumerState { ), ), ), + ), ), ); }