Flutter:如何创建带文本和线性进度指示器的原生启动页?
实现带文本和线性进度指示器的启动页
先明确核心限制
flutter_native_splash 生成的是原生平台的静态启动页(Android的Splash Screen、iOS的Launch Screen),这类启动页不支持动态组件(比如实时更新的进度条)。所以得拆两步实现:
- 用
flutter_native_splash生成和目标样式匹配的静态启动页(带背景色和文本) - 在Flutter初始化完成后,显示一个模拟原生启动页的过渡页面,在这个页面里添加动态进度指示器,直到应用初始化逻辑完成
第一步:更新flutter_native_splash配置
修改你的pubspec.yaml,添加静态文本(建议把文本做成图片,避免跨平台字体差异),示例配置如下:
dependencies: flutter_native_splash: ^2.2.19 flutter_native_splash: android: true ios: true web: false color: "#42a5f5" # 把做好的带文本的图片放在assets/images/目录下,记得在pubspec里配置assets路径 branding_image: "assets/images/splash_text.png" # 可选:调整图片宽度,适配不同屏幕 branding_image_width: 200
执行命令更新原生启动页文件:
flutter pub run flutter_native_splash:create
第二步:编写Flutter过渡页面添加动态进度条
在main.dart中实现过渡页面,模拟原生启动页样式,同时添加进度指示器:
import 'package:flutter/material.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // 替换成你的实际初始化逻辑(比如加载资源、请求接口) await _initApp(); runApp(const MyApp()); } // 模拟初始化过程,实际开发中替换为业务逻辑 Future<void> _initApp() async { await Future.delayed(const Duration(seconds: 3)); } class SplashTransitionPage extends StatefulWidget { final Future<void> Function() initTask; final Widget Function() onFinish; const SplashTransitionPage({ super.key, required this.initTask, required this.onFinish, }); @override State<SplashTransitionPage> createState() => _SplashTransitionPageState(); } class _SplashTransitionPageState extends State<SplashTransitionPage> { double _progress = 0.0; @override void initState() { super.initState(); _startInit(); } Future<void> _startInit() async { // 示例:分阶段更新进度,实际可根据初始化步骤调整 await Future.delayed(const Duration(milliseconds: 1000)); setState(() => _progress = 0.3); await Future.delayed(const Duration(milliseconds: 1000)); setState(() => _progress = 0.7); await Future.delayed(const Duration(milliseconds: 1000)); setState(() => _progress = 1.0); // 执行真实初始化任务 await widget.initTask(); // 跳转到主页 if (mounted) { Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (_) => widget.onFinish()), ); } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xff42a5f5), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 文本样式需和原生启动页保持一致 const Text( "正在加载...", style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 20), // 线性进度指示器 SizedBox( width: MediaQuery.of(context).size.width * 0.8, child: LinearProgressIndicator( value: _progress, backgroundColor: Colors.white.withOpacity(0.3), valueColor: const AlwaysStoppedAnimation<Color>(Colors.white), ), ), ], ), ), ); } } // 主页示例 class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Demo', theme: ThemeData(primarySwatch: Colors.blue), home: const Scaffold(body: Center(child: Text("主页"))), ); } }
补充说明
- 原生启动页会在Flutter初始化前先显示,之后无缝过渡到Flutter过渡页面,用户基本感知不到切换
- 如果需要精准的进度更新,可以在初始化函数中添加回调,实时修改
_progress的值 - 若不想用图片做文本,直接在Flutter过渡页面写文本即可,注意和原生启动页的字体、样式对齐
内容的提问来源于stack exchange,提问作者Divya
相关产品推荐
相关产品推荐

