import 'dart:io'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../../constants/app_constants.dart'; import '../../../config/app_config.dart'; import '../settings/privacy.dart'; import '../settings/user-plan.dart'; import 'permission.dart'; /// 时间: 2026-03-27 /// 功能: 引导页 /// 介绍: 展示欢迎语、隐私政策、功能介绍,支持垂直滑动切换 /// 最新变化: 支持所有页面垂直滑动,左侧显示页面进度指示器,集成协议内容,添加协议同意状态 class SpGuidePage extends StatefulWidget { final bool fromSettings; const SpGuidePage({super.key, this.fromSettings = false}); @override State createState() => _SpGuidePageState(); } class _SpGuidePageState extends State with TickerProviderStateMixin { final PageController _pageController = PageController(); TabController? _tabController; int _currentPage = 0; bool _firstLaunch = true; bool _showGuideOnStartup = false; bool _agreementAccepted = false; bool _userPlanJoined = false; // 协议焦点状态 bool _isAgreementFocused = false; final int _totalPages = 3; final List _pageTitles = ['欢迎使用', '双击中心区域查看协议', '了解软件功能']; @override void initState() { super.initState(); _loadSettings(); } @override void dispose() { _pageController.dispose(); _tabController?.dispose(); super.dispose(); } void _initTabController() { if (_tabController == null) { _tabController = TabController(length: 2, vsync: this); } } Future _loadSettings() async { final prefs = await SharedPreferences.getInstance(); setState(() { _firstLaunch = prefs.getBool(AppConfig.keyFirstLaunch) ?? true; _showGuideOnStartup = prefs.getBool(AppConfig.keyShowGuideOnStartup) ?? false; _agreementAccepted = prefs.getBool(AppConfig.keyAgreementAccepted) ?? false; _userPlanJoined = prefs.getBool(AppConfig.keyUserPlanJoined) ?? false; }); } Future _toggleShowGuide(bool value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool(AppConfig.keyShowGuideOnStartup, value); setState(() { _showGuideOnStartup = value; }); } Future _toggleUserPlan(bool value) async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool(AppConfig.keyUserPlanJoined, value); setState(() { _userPlanJoined = value; }); } Future _acceptAgreement() async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool(AppConfig.keyAgreementAccepted, true); await prefs.setBool(AppConfig.keyFirstLaunch, false); setState(() { _agreementAccepted = true; _firstLaunch = false; }); } Future _rejectAgreement() async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool(AppConfig.keyAgreementAccepted, false); setState(() { _agreementAccepted = false; }); } void _rejectAndExit() { showDialog( context: context, builder: (context) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), title: Row( children: [ Icon(Icons.exit_to_app, color: Colors.red[700]), const SizedBox(width: 8), const Text('退出确认'), ], ), content: const Text( '不同意协议将无法使用本软件,确定要退出吗?', style: TextStyle(fontSize: 14, height: 1.5), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), ElevatedButton( onPressed: () { Navigator.pop(context); exit(0); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.red, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text('确定退出'), ), ], ), ); } void _nextPage() { if (_currentPage < _totalPages - 1 && _pageController.hasClients) { _pageController.nextPage( duration: const Duration(milliseconds: 400), curve: Curves.easeInOut, ); } } void _previousPage() { if (_currentPage > 0 && _pageController.hasClients) { _pageController.previousPage( duration: const Duration(milliseconds: 400), curve: Curves.easeInOut, ); } } void _showNeedAcceptAgreementDialog() { showDialog( context: context, builder: (context) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), title: Row( children: [ Icon(Icons.warning_amber, color: Colors.orange[700]), const SizedBox(width: 8), const Text('提示'), ], ), content: const Text( '不同意退出', style: TextStyle(fontSize: 14, height: 1.5), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), ElevatedButton( onPressed: () { Navigator.pop(context); _acceptAgreement(); _nextPage(); }, style: ElevatedButton.styleFrom( backgroundColor: AppConstants.primaryColor, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: const Text('同意并继续'), ), ], ), ); } void _finishGuide() { if (!_agreementAccepted) { _showNeedAcceptAgreementDialog(); return; } if (widget.fromSettings) { Navigator.pop(context); } else { Navigator.pushReplacementNamed(context, '/home'); } } @override Widget build(BuildContext context) { return WillPopScope( // 拦截返回按钮,如果不是从设置页面进入,则阻止返回 onWillPop: () async { if (widget.fromSettings) { return true; // 允许返回 } // 首次启动时,阻止返回,必须完成引导流程 return false; }, child: Scaffold( backgroundColor: Colors.white, appBar: _buildAppBar(), body: Stack( children: [ PageView( controller: _pageController, scrollDirection: Axis.vertical, physics: const PageScrollPhysics(), onPageChanged: (index) { setState(() { _currentPage = index; }); }, children: [ _buildWelcomePage(), _buildPrivacyPage(), _buildFeaturePage(), ], ), _buildPageIndicator(), _buildBottomNavigation(), ], ), ), ); } Widget _buildPageIndicator() { // 根据当前页面计算进度条位置 // 第1页:屏幕上方靠近顶部 // 第2页:屏幕中间(不变) // 第3页:屏幕下方靠近底部 double alignmentY; switch (_currentPage) { case 0: alignmentY = -0.7; // 上方靠近顶部 break; case 1: alignmentY = 0.0; // 中间 break; case 2: alignmentY = 0.7; // 下方靠近底部 break; default: alignmentY = 0.0; } return Positioned( left: 16, top: 0, bottom: 0, child: Align( alignment: Alignment(0, alignmentY), child: Container( padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.9), borderRadius: BorderRadius.circular(24), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.1), blurRadius: 8, offset: const Offset(2, 0), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: List.generate(_totalPages, (index) { final isActive = index == _currentPage; final isCompleted = index < _currentPage; return GestureDetector( onTap: () { if (_pageController.hasClients) { _pageController.animateToPage( index, duration: const Duration(milliseconds: 400), curve: Curves.easeInOut, ); } }, child: Container( margin: const EdgeInsets.symmetric(vertical: 10), width: isActive ? 16 : 14, height: isActive ? 16 : 14, decoration: BoxDecoration( shape: BoxShape.circle, color: isActive ? AppConstants.primaryColor : isCompleted ? AppConstants.primaryColor.withValues(alpha: 0.5) : Colors.grey[300], border: isActive ? Border.all(color: AppConstants.primaryColor, width: 3) : null, boxShadow: isActive ? [ BoxShadow( color: AppConstants.primaryColor.withValues( alpha: 0.3, ), blurRadius: 8, spreadRadius: 2, ), ] : null, ), ), ); }), ), ), ), ); } PreferredSizeWidget _buildAppBar() { return AppBar( title: Text( _pageTitles[_currentPage], style: TextStyle( color: AppConstants.primaryColor, fontWeight: FontWeight.bold, ), ), backgroundColor: Colors.white, elevation: 0, centerTitle: true, leading: widget.fromSettings ? IconButton( icon: Icon(Icons.arrow_back, color: AppConstants.primaryColor), onPressed: () => Navigator.pop(context), ) : null, automaticallyImplyLeading: false, ); } Widget _buildWelcomePage() { return Container( padding: const EdgeInsets.all(32), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 120, height: 120, decoration: BoxDecoration( gradient: LinearGradient( colors: [ AppConstants.primaryColor.withValues(alpha: 0.1), AppConstants.primaryColor.withValues(alpha: 0.05), ], ), borderRadius: BorderRadius.circular(30), ), child: const Center( child: Text('📖', style: TextStyle(fontSize: 60)), ), ), const SizedBox(height: 40), const Text( '欢迎使用', style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, color: Colors.black87, ), ), const SizedBox(height: 16), Text( '情景诗词', style: TextStyle( fontSize: 24, fontWeight: FontWeight.w600, color: AppConstants.primaryColor, ), ), const SizedBox(height: 32), Container( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), decoration: BoxDecoration( color: Colors.grey[50], borderRadius: BorderRadius.circular(16), ), child: Column( children: [ _buildWelcomeItem('🌟', '在诗词里旅行,在文化中生长'), const SizedBox(height: 16), _buildWelcomeItem('📚', '海量诗词,随心阅读'), const SizedBox(height: 16), _buildWelcomeItem('❤️', '收藏喜爱,记录感悟'), const SizedBox(height: 16), _buildWelcomeItem('🌙', '每日推荐,发现美好'), ], ), ), const SizedBox(height: 40), Container( margin: const EdgeInsets.only(left: 16), height: 1, width: double.infinity, color: Colors.grey[300], ), const SizedBox(height: 16), Text( '向上滑动继续 ↓', style: TextStyle(fontSize: 14, color: Colors.grey[400]), ), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton.icon( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const PermissionPage(), ), ); }, icon: Icon( Icons.security, size: 18, color: AppConstants.primaryColor, ), label: Text( '了解软件权限', style: TextStyle( color: AppConstants.primaryColor, fontSize: 14, ), ), style: TextButton.styleFrom( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), side: BorderSide( color: AppConstants.primaryColor.withValues(alpha: 0.3), ), ), ), ), const SizedBox(width: 8), // _buildShowGuideCheckbox(), ], ), ], ), ); } Widget _buildWelcomeItem(String emoji, String text) { return Row( children: [ Text(emoji, style: const TextStyle(fontSize: 20)), const SizedBox(width: 12), Expanded( child: Text( text, style: const TextStyle(fontSize: 15, color: Colors.black87), ), ), ], ); } Widget _buildShowGuideCheckbox() { return GestureDetector( onTap: () { _toggleShowGuide(!_showGuideOnStartup); _showGuideStatusPopup(); }, child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.1), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Icon( _showGuideOnStartup ? Icons.check_box : Icons.check_box_outline_blank, color: _showGuideOnStartup ? AppConstants.primaryColor : Colors.grey[400], size: 24, ), ), ); } void _showGuideStatusPopup() { showDialog( context: context, builder: (context) => Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.15), blurRadius: 20, offset: const Offset(0, 4), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( children: [ Icon( _showGuideOnStartup ? Icons.check_circle : Icons.info_outline, color: _showGuideOnStartup ? AppConstants.primaryColor : Colors.grey[600], size: 24, ), const SizedBox(width: 8), const Text( '通知设置', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ], ), const SizedBox(height: 16), Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: _showGuideOnStartup ? AppConstants.primaryColor.withValues(alpha: 0.1) : Colors.grey[50], borderRadius: BorderRadius.circular(12), ), child: Column( children: [ Icon( _showGuideOnStartup ? Icons.notifications_active : Icons.notifications_off, color: _showGuideOnStartup ? AppConstants.primaryColor : Colors.grey[500], size: 40, ), const SizedBox(height: 12), Text( _showGuideOnStartup ? '已开启' : '已关闭', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: _showGuideOnStartup ? AppConstants.primaryColor : Colors.grey[700], ), ), const SizedBox(height: 8), Text( _showGuideOnStartup ? '下次启动时将显示欢迎页' : '下次启动时将不显示欢迎页', style: TextStyle(fontSize: 14, color: Colors.grey[600]), textAlign: TextAlign.center, ), ], ), ), const SizedBox(height: 16), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () => Navigator.pop(context), style: ElevatedButton.styleFrom( backgroundColor: AppConstants.primaryColor, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), child: const Text('知道了'), ), ), ], ), ), ), ); } Widget _buildPrivacyPage() { _initTabController(); return Stack( children: [ Column( children: [ Container( color: Colors.white, child: TabBar( controller: _tabController!, labelColor: AppConstants.primaryColor, unselectedLabelColor: Colors.grey[600], indicatorColor: AppConstants.primaryColor, indicatorWeight: 2, tabs: const [ Tab(text: '《隐私政策》'), Tab(text: '《用户协议》'), ], ), ), Expanded( child: Stack( children: [ // 协议内容区域 TabBarView( controller: _tabController!, physics: _isAgreementFocused ? const AlwaysScrollableScrollPhysics() : const NeverScrollableScrollPhysics(), children: [ // 隐私政策 - 使用 NotificationListener 监听滚动 NotificationListener( onNotification: (notification) { if (notification is ScrollEndNotification) { final metrics = notification.metrics; // 只有在到达顶部或底部时才取消焦点 if (metrics.pixels <= metrics.minScrollExtent || metrics.pixels >= metrics.maxScrollExtent) { setState(() { _isAgreementFocused = false; }); } } return false; }, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { setState(() { _isAgreementFocused = true; }); }, child: const Padding( padding: EdgeInsets.all(16), child: PrivacyPolicyContent(), ), ), ), ), // 用户协议 - 使用 NotificationListener 监听滚动 NotificationListener( onNotification: (notification) { if (notification is ScrollEndNotification) { final metrics = notification.metrics; // 只有在到达顶部或底部时才取消焦点 if (metrics.pixels <= metrics.minScrollExtent || metrics.pixels >= metrics.maxScrollExtent) { setState(() { _isAgreementFocused = false; }); } } return false; }, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { setState(() { _isAgreementFocused = true; }); }, child: const Padding( padding: EdgeInsets.all(16), child: UserAgreementContent(), ), ), ), ), ], ), // 左右焦点竖线 if (_isAgreementFocused) Positioned( left: 0, top: 0, bottom: 0, child: Container( width: 3, color: AppConstants.primaryColor, ), ), if (_isAgreementFocused) Positioned( right: 0, top: 0, bottom: 0, child: Container( width: 3, color: AppConstants.primaryColor, ), ), ], ), ), ], ), // 底部按钮区域 - 点击时取消协议焦点 Positioned( left: 0, right: 0, bottom: 0, child: GestureDetector( onTap: () { if (_isAgreementFocused) { setState(() { _isAgreementFocused = false; }); } }, child: Container( padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 10, offset: const Offset(0, -2), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( height: 1, width: double.infinity, color: Colors.grey[300], ), const SizedBox(height: 16), Row( children: [ Checkbox( value: _agreementAccepted, onChanged: (value) { if (value == true) { _acceptAgreement(); } else { _rejectAgreement(); } }, activeColor: AppConstants.primaryColor, ), Expanded( child: GestureDetector( onTap: () { if (_agreementAccepted) { _rejectAgreement(); } else { _acceptAgreement(); } }, child: Text( '我已阅读并同意隐私政策和用户协议', style: TextStyle( fontSize: 14, color: _agreementAccepted ? AppConstants.primaryColor : Colors.grey[700], ), ), ), ), ], ), const SizedBox(height: 8), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _agreementAccepted ? _nextPage : _rejectAndExit, style: ElevatedButton.styleFrom( backgroundColor: _agreementAccepted ? AppConstants.primaryColor : Colors.grey[600], foregroundColor: Colors.white, disabledBackgroundColor: Colors.grey[300], padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: Text( _agreementAccepted ? '已同意,继续' : '不同意退出', style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w600, ), ), ), ), ], ), ), ), ), ], ); } Widget _buildFeaturePage() { return Padding( padding: const EdgeInsets.fromLTRB(24, 16, 24, 100), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Center( // child: Container( // width: 80, // height: 80, // decoration: BoxDecoration( // color: Colors.purple.withValues(alpha: 0.1), // borderRadius: BorderRadius.circular(20), // ), // child: const Center( // child: Text('✨', style: TextStyle(fontSize: 40)), // ), // ), // ), // const SizedBox(height: 24), // const Center( // child: Text( // '功能介绍', // style: TextStyle( // fontSize: 26, // fontWeight: FontWeight.bold, // color: Colors.black87, // ), // ), // ), // const SizedBox(height: 8), Center( child: Text( '探索丰富的诗词世界', style: TextStyle(fontSize: 14, color: Colors.grey[600]), ), ), const SizedBox(height: 16), Column( children: [ Row( children: [ Expanded( child: _buildFeatureCard( '🏠 首页', '每日推荐精选诗词', Icons.home, Colors.blue, ), ), const SizedBox(width: 8), Expanded( child: _buildFeatureCard( '🔍 发现', '浏览排行榜、分类', Icons.explore, Colors.green, ), ), ], ), const SizedBox(height: 8), Row( children: [ Expanded( child: _buildFeatureCard( '❤️ 收藏', '点赞收藏、记笔记', Icons.favorite, Colors.red, ), ), const SizedBox(width: 8), Expanded( child: _buildFeatureCard( '👤 个人', '管理数据、设置', Icons.person, Colors.purple, ), ), ], ), ], ), const SizedBox(height: 20), Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), decoration: BoxDecoration( color: Colors.grey[50], borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon( Icons.volunteer_activism, color: AppConstants.primaryColor, size: 18, ), const SizedBox(width: 8), Expanded( child: GestureDetector( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const UserPlanPage(), ), ).then((_) { _loadSettings(); }); }, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '用户体验计划', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 2), Text( '参与产品改进,享受更多权益', style: TextStyle( fontSize: 11, color: Colors.grey[600], ), ), ], ), ), ), Switch( value: _userPlanJoined, onChanged: _toggleUserPlan, activeColor: AppConstants.primaryColor, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, ), ], ), ), const SizedBox(height: 6), Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: _agreementAccepted ? Colors.green.withValues(alpha: 0.1) : Colors.orange.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon( _agreementAccepted ? Icons.check_circle : Icons.info, color: _agreementAccepted ? Colors.green[700] : Colors.orange[700], size: 18, ), const SizedBox(width: 8), Expanded( child: Text( _agreementAccepted ? '已同意软件协议' : '未同意软件协议', style: TextStyle( fontSize: 12, color: _agreementAccepted ? Colors.green[700] : Colors.orange[700], ), ), ), ], ), ), const SizedBox(height: 6), Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: _userPlanJoined ? Colors.blue.withValues(alpha: 0.1) : Colors.grey.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon( _userPlanJoined ? Icons.volunteer_activism : Icons.info_outline, color: _userPlanJoined ? Colors.blue[700] : Colors.grey[600], size: 18, ), const SizedBox(width: 8), Expanded( child: Text( _userPlanJoined ? '已加入体验计划' : '未加入体验计划', style: TextStyle( fontSize: 12, color: _userPlanJoined ? Colors.blue[700] : Colors.grey[600], ), ), ), ], ), ), const SizedBox(height: 16), SizedBox( width: double.infinity, height: 44, child: ElevatedButton( onPressed: _finishGuide, style: ElevatedButton.styleFrom( backgroundColor: AppConstants.primaryColor, foregroundColor: Colors.white, padding: EdgeInsets.zero, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), elevation: 2, ), child: const Text( '开始使用', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600), ), ), ), const SizedBox(height: 16), ], ), ); } Widget _buildFeatureCard( String title, String desc, IconData icon, Color color, ) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey.withValues(alpha: 0.2)), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.03), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 40, height: 40, decoration: BoxDecoration( color: color.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(10), ), child: Icon(icon, color: color, size: 20), ), const SizedBox(height: 8), Text( title, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600), ), const SizedBox(height: 2), Text( desc, style: TextStyle( fontSize: 11, color: Colors.grey[600], height: 1.3, ), ), ], ), ); } Widget _buildBottomNavigation() { return Positioned( bottom: 0, left: 0, right: 0, child: Container( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 20), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _currentPage > 0 ? _buildNavButton( icon: Icons.arrow_back_ios, label: '上一页', onPressed: _previousPage, ) : const SizedBox(width: 100), _currentPage < _totalPages - 1 ? _buildNavButton( icon: Icons.arrow_forward_ios, label: '下一页', onPressed: _currentPage == 1 && !_agreementAccepted ? null : _nextPage, ) : _buildNavButton( icon: Icons.check, label: '完成', onPressed: _agreementAccepted ? _finishGuide : null, ), ], ), ), ); } Widget _buildNavButton({ required IconData icon, required String label, VoidCallback? onPressed, }) { return Container( decoration: BoxDecoration( color: onPressed != null ? AppConstants.primaryColor : Colors.grey[300], borderRadius: BorderRadius.circular(12), boxShadow: onPressed != null ? [ BoxShadow( color: AppConstants.primaryColor.withValues(alpha: 0.3), blurRadius: 8, offset: const Offset(0, 2), ), ] : null, ), child: Material( color: Colors.transparent, child: InkWell( onTap: onPressed, borderRadius: BorderRadius.circular(12), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( icon, color: onPressed != null ? Colors.white : Colors.grey[500], size: 20, ), const SizedBox(width: 8), Text( label, style: TextStyle( color: onPressed != null ? Colors.white : Colors.grey[500], fontSize: 14, fontWeight: FontWeight.w500, ), ), ], ), ), ), ), ); } }