Flutter多页面协作获取API数据并实现加载过渡展示方案
Flutter页面跳转与异步数据加载问题解决方案
问题背景
现有Flutter程序流程:首页展示→获取用户输入→调用自研REST API获取数据。需新增以下逻辑:
- API加载数据时显示Spinkit加载界面
- 点击首页按钮后,先跳转至加载页,待数据完全加载后,跳转至携带该数据的目标展示页
当前存在问题:
- 按钮
onPressed中添加页面跳转代码会阻塞后续数据获取执行 - 展示页无异步函数,无法通过
await获取数据
解决方案
1. 重构首页按钮点击逻辑
移除首页按钮中数据获取的逻辑,改为直接跳转到加载页并传递用户输入参数,避免跳转阻塞异步操作:
onPressed: () { // 假设通过inputController获取用户输入内容 final userInput = inputController.text; Navigator.push( context, MaterialPageRoute( builder: (context) => LoadingPage(userInput: userInput), ), ); },
2. 实现加载页(集成Spinkit)
创建加载页,在页面初始化时启动异步数据请求,请求完成后跳转至展示页并传递数据,同时处理异常场景:
class LoadingPage extends StatefulWidget { final String userInput; const LoadingPage({super.key, required this.userInput}); @override State<LoadingPage> createState() => _LoadingPageState(); } class _LoadingPageState extends State<LoadingPage> { @override void initState() { super.initState(); // 页面初始化后立即启动数据请求 _fetchAndNavigate(); } Future<void> _fetchAndNavigate() async { try { // 调用你的数据获取方法,传入用户输入 final apiData = await fetchData(widget.userInput); // 确保页面未销毁时跳转,替换当前加载页为展示页 if (mounted) { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => DisplayPage(data: apiData), ), ); } } catch (error) { // 处理请求错误,提示用户后返回首页 if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('数据加载失败:$error')), ); Navigator.pop(context); } } } @override Widget build(BuildContext context) { return Scaffold( body: Center( // 渲染Spinkit加载组件 child: SpinKitFadingCircle( color: Colors.blue, size: 50.0, ), ), ); } }
3. 修改展示页接收数据
展示页通过构造函数直接接收已加载完成的数据,无需处理异步逻辑,直接渲染UI:
// 替换YourDataType为你的实际数据模型类型 class DisplayPage extends StatelessWidget { final YourDataType data; const DisplayPage({super.key, required this.data}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('数据展示')), body: Padding( padding: const EdgeInsets.all(16.0), // 直接使用传入的数据渲染界面 child: Text(data.toString()), ), ); } }
4. 确保数据获取函数为异步类型
确认你的数据获取函数是异步方法,能正确返回解析后的数据模型:
Future<YourDataType> fetchData(String userInput) async { // 替换为你的自研API调用逻辑 final response = await http.get( Uri.parse('https://your-api-domain.com/endpoint?input=$userInput'), ); if (response.statusCode == 200) { // 将JSON响应解析为自定义数据模型 return YourDataType.fromJson(jsonDecode(response.body)); } else { throw Exception('请求失败,状态码:${response.statusCode}'); } }
方案说明
- 首页仅负责跳转逻辑,不会阻塞异步数据请求,解决了跳转阻塞后续代码的问题
- 加载页承担异步数据获取的职责,同时展示加载状态,符合需求流程
- 展示页通过构造函数直接获取已加载的数据,无需处理异步操作,避免了
await的限制
内容的提问来源于stack exchange,提问作者ash2021
相关产品推荐
相关产品推荐

