diff --git a/frontend/mobile-app/assets/images/splash_static/splash_1.jpg b/frontend/mobile-app/assets/images/splash_static/splash_1.jpg new file mode 100644 index 00000000..529d4f12 Binary files /dev/null and b/frontend/mobile-app/assets/images/splash_static/splash_1.jpg differ diff --git a/frontend/mobile-app/assets/images/splash_static/splash_2.jpg b/frontend/mobile-app/assets/images/splash_static/splash_2.jpg new file mode 100644 index 00000000..1c635e47 Binary files /dev/null and b/frontend/mobile-app/assets/images/splash_static/splash_2.jpg differ diff --git a/frontend/mobile-app/assets/images/splash_static/splash_3.jpg b/frontend/mobile-app/assets/images/splash_static/splash_3.jpg new file mode 100644 index 00000000..71635354 Binary files /dev/null and b/frontend/mobile-app/assets/images/splash_static/splash_3.jpg differ diff --git a/frontend/mobile-app/lib/features/auth/presentation/pages/splash_page.dart b/frontend/mobile-app/lib/features/auth/presentation/pages/splash_page.dart index 79266853..4d183456 100644 --- a/frontend/mobile-app/lib/features/auth/presentation/pages/splash_page.dart +++ b/frontend/mobile-app/lib/features/auth/presentation/pages/splash_page.dart @@ -1,3 +1,4 @@ +import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; @@ -10,7 +11,7 @@ import '../../../../routes/app_router.dart'; import '../providers/auth_provider.dart'; /// 开屏页面 - 应用启动时显示的第一个页面 -/// 播放帧动画,动画结束后检查用户认证状态并跳转 +/// 随机显示一张静态图片,3秒后自动跳转 class SplashPage extends ConsumerStatefulWidget { const SplashPage({super.key}); @@ -19,6 +20,22 @@ class SplashPage extends ConsumerStatefulWidget { } class _SplashPageState extends ConsumerState { + // ========== 静态图片模式配置 ========== + + /// 是否使用静态图片模式(false = 使用帧动画) + static const bool _useStaticImage = true; + + /// 静态图片显示时长(秒) + static const int _staticDisplaySeconds = 3; + + /// 静态图片数量 + static const int _staticImageCount = 3; + + /// 当前显示的静态图片索引 (1-based) + late int _staticImageIndex; + + // ========== 帧动画模式配置(保留备用) ========== + /// 帧动画总帧数 static const int _totalFrames = 36; @@ -28,25 +45,55 @@ class _SplashPageState extends ConsumerState { /// 当前显示的帧索引 (0-based) int _currentFrameIndex = 0; + /// 预加载的图片缓存(帧动画用) + final List _frameProviders = []; + + // ========== 通用状态 ========== + /// 是否显示跳过按钮 bool _showSkipButton = false; /// 是否已经开始跳转(防止重复跳转) bool _isNavigating = false; - /// 帧动画是否正在播放 + /// 动画/计时器是否正在运行 bool _isPlaying = true; - /// 预加载的图片缓存 - final List _frameProviders = []; - @override void initState() { super.initState(); - _initializeFrames(); + + if (_useStaticImage) { + _initializeStaticImage(); + } else { + _initializeFrames(); + } } - /// 初始化帧动画 + /// 初始化静态图片模式 + void _initializeStaticImage() { + // 随机选择一张图片 (1 到 _staticImageCount) + _staticImageIndex = Random().nextInt(_staticImageCount) + 1; + debugPrint('[SplashPage] 静态图片模式:显示 splash_$_staticImageIndex.jpg'); + + // 3秒后自动跳转 + Future.delayed(Duration(seconds: _staticDisplaySeconds), () { + if (mounted && _isPlaying) { + _navigateToNextPage(); + } + }); + + // 1秒后显示跳过按钮 + Future.delayed(const Duration(seconds: 1), () { + if (mounted) { + setState(() { + _showSkipButton = true; + }); + } + }); + } + + /// 初始化帧动画(保留备用) void _initializeFrames() { // 创建所有帧的 ImageProvider(不会立即加载,只是创建引用) for (int i = 1; i <= _totalFrames; i++) { @@ -71,11 +118,20 @@ class _SplashPageState extends ConsumerState { @override void didChangeDependencies() { super.didChangeDependencies(); - // 预加载前几帧到内存,确保播放流畅 - _precacheInitialFrames(); + + if (_useStaticImage) { + // 预加载静态图片 + precacheImage( + AssetImage('assets/images/splash_static/splash_$_staticImageIndex.jpg'), + context, + ); + } else { + // 预加载前几帧到内存,确保播放流畅 + _precacheInitialFrames(); + } } - /// 预加载前几帧 + /// 预加载前几帧(帧动画用) void _precacheInitialFrames() { // 预加载前5帧,确保启动时不卡顿 final framesToPrecache = _totalFrames < 5 ? _totalFrames : 5; @@ -84,7 +140,7 @@ class _SplashPageState extends ConsumerState { } } - /// 播放帧动画 + /// 播放帧动画(保留备用) Future _playAnimation() async { final frameDuration = Duration(milliseconds: 1000 ~/ _frameRate); @@ -110,7 +166,7 @@ class _SplashPageState extends ConsumerState { } } - /// 跳过动画 + /// 跳过动画/等待 void _skipAnimation() { _isPlaying = false; _navigateToNextPage(); @@ -222,8 +278,8 @@ class _SplashPageState extends ConsumerState { body: Stack( fit: StackFit.expand, children: [ - // 帧动画(全屏覆盖) - _buildFrameAnimation(), + // 启动图片/动画(全屏覆盖) + _useStaticImage ? _buildStaticImage() : _buildFrameAnimation(), // 跳过按钮 if (_showSkipButton) @@ -237,7 +293,17 @@ class _SplashPageState extends ConsumerState { ); } - /// 构建帧动画视图 + /// 构建静态图片视图 + Widget _buildStaticImage() { + return SizedBox.expand( + child: Image.asset( + 'assets/images/splash_static/splash_$_staticImageIndex.jpg', + fit: BoxFit.cover, + ), + ); + } + + /// 构建帧动画视图(保留备用) Widget _buildFrameAnimation() { return SizedBox.expand( child: Image( diff --git a/frontend/mobile-app/pubspec.yaml b/frontend/mobile-app/pubspec.yaml index c8347aef..f5ad615f 100644 --- a/frontend/mobile-app/pubspec.yaml +++ b/frontend/mobile-app/pubspec.yaml @@ -109,6 +109,7 @@ flutter: - assets/images/avatars/ - assets/images/illustrations/ - assets/images/splash_frames/ + - assets/images/splash_static/ - assets/icons/ - assets/icons/nav/ - assets/icons/tokens/