Flutter for OpenHarmony:从零搭建今日资讯App(二)启动页实现

启动页是用户打开应用看到的第一个界面,需要实现Logo展示、淡入动画和自动跳转功能。一个设计精美、过渡流畅的启动页,能让用户感觉应用很专业。
启动页功能需求
在动手写代码之前,先明确启动页要实现的功能:
视觉展示 - 显示应用Logo和名称,传达品牌形象
过渡动画 - 淡入动画让过渡更自然,提升用户体验
自动跳转 - 延时几秒后自动跳转到主页面
资源释放 - 正确释放动画资源,避免内存泄漏
创建启动页文件
在lib/screens目录下创建splash_screen.dart:
import 'package:flutter/material.dart';
import 'main_screen.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
State<SplashScreen> createState() => _SplashScreenState();
}
代码解析:
- 使用
StatefulWidget因为需要处理动画和延时跳转 - 导入
main_screen.dart用于跳转到主页面 - 启动页也是一个页面,所以放在screens目录
配置动画控制器
class _SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _fadeAnimation;
代码解析:
SingleTickerProviderStateMixin- 提供动画"心跳",驱动动画运行late- 延迟初始化,在initState中赋值AnimationController- 控制动画的播放、暂停、停止Animation<double>- 透明度动画,值从0到1
为什么需要SingleTickerProviderStateMixin:动画需要一个"心跳"来驱动,这个mixin就提供了这个心跳。如果页面有多个动画,用TickerProviderStateMixin。
初始化动画和跳转
void initState() {
super.initState();
// 创建动画控制器
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
// 创建淡入动画
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
// 启动动画
_controller.forward();
// 延时跳转
Future.delayed(const Duration(seconds: 3), () {
if (mounted) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const MainScreen()),
);
}
});
}
代码解析:
duration: Duration(seconds: 2)- 动画持续2秒,时间要把握好vsync: this- 传入"心跳",this就是SingleTickerProviderStateMixinTween<double>(begin: 0.0, end: 1.0)- 透明度从0(完全透明)到1(完全不透明)_controller.forward()- 启动动画,让透明度从0变到1Future.delayed- 延迟3秒后跳转,动画2秒+停留1秒mounted- 检查Widget是否还在树中,避免跳转时报错pushReplacement- 替换当前页面,用户无法返回启动页
为什么是3秒:动画2秒,再多停留1秒让用户看清楚Logo。太短看不清,太长用户会不耐烦。
释放资源
void dispose() {
_controller.dispose();
super.dispose();
}
代码解析:
- 在dispose中释放AnimationController,避免内存泄漏
- 所有手动管理的资源(动画控制器、文本控制器、滚动控制器等)都要在dispose里释放
- 这是个好习惯,养成后可以避免很多内存问题
构建UI界面
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.secondary,
],
),
),
代码解析:
Scaffold- Flutter的脚手架Widget,提供Material Design基本布局BoxDecoration- 添加装饰效果LinearGradient- 线性渐变背景,从左上到右下- 使用主题颜色,自动适配深色/浅色模式
为什么用渐变背景:纯色背景太单调,渐变背景更有设计感,既美观又能体现应用的品牌色。
添加Logo和文字
child: Center(
child: FadeTransition(
opacity: _fadeAnimation,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(
Icons.newspaper,
size: 100,
color: Colors.white,
),
SizedBox(height: 24),
Text(
'今日资讯',
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(height: 8),
Text(
'随时随地,掌握最新资讯',
style: TextStyle(
fontSize: 16,
color: Colors.white70,
),
),
],
),
),
),
),
);
}
}
代码解析:
FadeTransition- 淡入淡出动画Widget,根据opacity值改变透明度Icon(Icons.newspaper)- 新闻图标,大小100,颜色白色- 主标题字号32,加粗显示,让标题更醒目
- 副标题字号16,透明度70%,形成层次感
SizedBox- 控制间距,24和8是经过调整的最佳值
图标的选择:用Material Icons的newspaper图标,因为我们是新闻应用。实际项目中,可以用自己设计的Logo图片,用Image.asset()加载。
完整代码
完整的splash_screen.dart文件:
import 'package:flutter/material.dart';
import 'main_screen.dart';
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
late Animation<double> _fadeAnimation;
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
);
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
_controller.forward();
Future.delayed(const Duration(seconds: 3), () {
if (mounted) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const MainScreen()),
);
}
});
}
void dispose() {
_controller.dispose();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Theme.of(context).colorScheme.primary,
Theme.of(context).colorScheme.secondary,
],
),
),
child: Center(
child: FadeTransition(
opacity: _fadeAnimation,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(
Icons.newspaper,
size: 100,
color: Colors.white,
),
SizedBox(height: 24),
Text(
'今日资讯',
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
SizedBox(height: 8),
Text(
'随时随地,掌握最新资讯',
style: TextStyle(
fontSize: 16,
color: Colors.white70,
),
),
],
),
),
),
),
);
}
}
整个文件不到100行,但实现了淡入动画、延时跳转、渐变背景等效果。代码简洁清晰,易于维护。
运行测试
flutter run
注意:要完整测试启动页,需要重新启动应用(按R热重启),热重载(r)看不到启动页,因为启动页只在应用启动时显示一次。
应用启动后会看到:
- 渐变背景从左上到右下
- Logo和文字淡入显示(2秒)
- 停留1秒后自动跳转到主页面
如果动画不够流畅,可能是模拟器性能不够。在真机上测试会流畅很多。
优化建议
添加版本号显示
可以在启动页底部显示应用版本号:
Positioned(
bottom: 50,
child: Text(
'v1.0.0',
style: TextStyle(color: Colors.white60, fontSize: 12),
),
)
实际项目中,版本号应该从package_info_plus包动态获取,而不是硬编码。
添加加载指示器
如果启动时要加载数据,可以在底部加个加载指示器:
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
)
动态时长控制
实现动态时长,数据加载完就跳转,但至少显示2秒,最多5秒:
final minDuration = Duration(seconds: 2);
final maxDuration = Duration(seconds: 5);
final startTime = DateTime.now();
// 加载数据
await loadData().timeout(maxDuration);
// 确保至少显示minDuration
final elapsed = DateTime.now().difference(startTime);
if (elapsed < minDuration) {
await Future.delayed(minDuration - elapsed);
}
这段代码确保启动页至少显示2秒(让用户看到品牌),但不超过5秒(避免等待太久)。
处理返回键
Android用户可能在启动页按返回键,这时候应该直接退出应用:
WillPopScope(
onWillPop: () async {
return true; // 允许返回,会退出应用
},
child: Scaffold(...),
)
设计原则
做启动页时要遵循的原则:
简洁至上 - 只需要Logo、名称、Slogan就够了,不要放太多内容
品牌一致 - 配色、字体、风格要和应用整体保持一致
性能优先 - 要快速加载,不要用太大的图片或复杂的动画
适配主题 - 支持深色模式,不要在深色模式下显示刺眼的白色背景
避免广告 - 不要在启动页放广告,这是最糟糕的做法
启动页时长的思考
启动页显示多久合适?这需要平衡用户体验和品牌展示:
太短的问题(1秒):用户可能还没看清Logo就跳转了,失去了品牌展示的意义
太长的问题(5秒以上):用户会觉得应用启动慢,体验很差
建议时长:2-3秒最合适,既能展示品牌,又不会让用户等太久
如果需要加载数据,最多5秒,超时就跳转。用户可以进入主页面后再加载数据。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
在这里你可以找到更多Flutter开发资源,与其他开发者交流经验,共同进步。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)