分享

Flutter异步加载FutureBuilder重绘解决方案

 程序员读书空间 2022-11-17 发布于浙江

题记:

当你在沉睡,我听得见自己的悲鸣,穿透骨髓,在眼睛里无数次破碎;

尘埃与硝烟,我看得见疼痛如心碎,重叠心底的眼泪,燃烧出血液中的无畏。


通过FutureBuilder组件可实现在Flutter中将异步加载的数据更新显示到对应的组件上,基本使用代码如下:


/// 异步加载组件的基本使用class FutureBuilderPage extends StatefulWidget { @override _TestPageState createState() => _TestPageState();}
/// 异步加载组件的基本使用class _TestPageState extends State { ///这里的泛型就是异步加载的数据类型 ///可自定义 Future<String> _loadingFuture;
@override void initState() { super.initState(); _loadingFuture = loadingDataFunction(); }
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("异步加载数据"),), body: FutureBuilder<String>( //future:这个参数需要一个Future 对象,类似于 网络请求、IO future: _loadingFuture, ///这里的数据格式与上述FutureBuilder设置的泛型格式一至 initialData: "初始化的数据", ///构建显示的 Widget 会根据加载的状态来多次回调些方法 builder: (BuildContext context, AsyncSnapshot<String> snapshot) { //加载状态判断 switch (snapshot.connectionState) {
///可理解为初始加载显示的 Widget 异步加载开始时的回调 case ConnectionState.none: return Text('Result: ${snapshot.data}');
///异步加载中的回调 case ConnectionState.active: case ConnectionState.waiting: return CircularProgressIndicator();
///异步加载完成的回调 case ConnectionState.done: //判断是否加载失败 if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } else { ///通过 [snapshot.data]来获取异步加载的数据 return Text('Result: ${snapshot.data}'); } } return null; }, ), ); }
///模拟耗时的网络请求 Future<String> loadingDataFunction() async { ///模拟 await Future.delayed(Duration(milliseconds: 4000));
return Future.value("加载成功"); }}


运行效果如下:

需要特别注意的是为防止FutureBuilder组件的重绘问题,异步加载loadingFuture需要单独定义,一般定义在初始化函数中,另一种方式是结合AsyncMemoizer异步寄存器来保证异步加载只执行一次,在使用时使用别导包如下

import 'package:async/async.dart' show AsyncMemoizer;

然后对应的使用代码如下:


/// 异步加载组件的基本使用class FutureBuilderPage2 extends StatefulWidget { @override _TestPageState createState() => _TestPageState();}
/// 异步加载组件的基本使用class _TestPageState extends State {
///定义异步寄存器 AsyncMemoizer _memoization = AsyncMemoizer<String>(); ///模拟耗时的网络请求 Future<String> loadingDataFunction() async { ///模拟 await Future.delayed(Duration(milliseconds: 4000)); return Future.value("加载成功"); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("异步加载数据"), ), body: FutureBuilder<String>( //future:这个参数需要一个Future 对象,类似于 网络请求、IO future: _memoization.runOnce(loadingDataFunction), ///这里的数据格式与上述FutureBuilder设置的泛型格式一至 initialData: "初始化的数据", ///构建显示的 Widget 会根据加载的状态来多次回调些方法 builder: (BuildContext context, AsyncSnapshot<String> snapshot) { //加载状态判断 switch (snapshot.connectionState) {
///可理解为初始加载显示的 Widget 异步加载开始时的回调 case ConnectionState.none: return Text('Result: ${snapshot.data}');
///异步加载中的回调 case ConnectionState.active: case ConnectionState.waiting: return CircularProgressIndicator();
///异步加载完成的回调 case ConnectionState.done: //判断是否加载失败 if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } else { ///通过 [snapshot.data]来获取异步加载的数据 return Text('Result: ${snapshot.data}'); } } return null; }, ), ); }}

完毕

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约