FLutter入门:异步加载组件FutureBuilder

简介: FutureBuilder在实际开发中,进入一个页面后执行网络请求加载数据并显示是非常普遍的,这时候我们一般会显示loading直到加载完成显示正常页面。在flutter中我们可以在initState中发起异步请求,然后将请求结果赋值给data,并setState刷新页面,在build中可以这样实现

FutureBuilder


在实际开发中,进入一个页面后执行网络请求加载数据并显示是非常普遍的,这时候我们一般会显示loading直到加载完成显示正常页面。在flutter中我们可以在initState中发起异步请求,然后将请求结果赋值给data,并setState刷新页面,在build中可以这样实现


if(data == null){
    return _LoadingWidget()
}
else{
    return ...
}
复制代码


实际上flutter提供了一个FutureBuilder专门来处理需要异步的组件,下面是一个简单的示例:


var _future = Future.delayed(Duration(seconds: 3), () {
    return '服务器返回的数据';
  });
FutureBuilder(
      future: _future,
      builder: (context, snapshot) {
        var widget;
        if (snapshot.connectionState == ConnectionState.done) {
          if (snapshot.hasError) {
            widget = Text("出错了");
          } else {
            widget = Text(snapshot.data);
          }
        } else {
          widget = Padding(
            padding: EdgeInsets.all(20),
            child: CircularProgressIndicator(),
          );
        }
        return Center(
          child: widget,
        );
      },
    );
复制代码


可以看到FutureBuilder有两个主要属性

  • future:异步处理的任务。比如请求数据,读取文件等等
  • builder:创建widget。其中它的snapshot是该组件当前的状态,我们通过它来实现组件的切换。

snapshot的connectionState表示异步任务的状态,如果是ConnectionState.done表示任务完成,这时候通过snapshot.hasError来区分是出错(显示错误)还是正常完成(显示数据);否则就表示任务在执行中(显示laoding)。我们通过这些状态来返回不同的组件来实现异步加载的过程。

当任务正常完成(ConnectionState.done且snapshot.hasError为false)时,我们可以通过snapshot.data来获取异步返回的数据,再渲染页面即可。


防止FutureBuilder重绘


FutureBuilder是一个StatefulWidget控件,如果父节点重绘rebuild那么FutureBuilder也会重绘,但是这时候可能我们根本不是要请求数据,可能仅仅是更新页面上的一个文案,这样就会造成不必要的浪费和消耗,我们要尽量避免,所以就需要防止FutureBuilder重绘。

FutureBuilder重绘源码如下:


@override
  void didUpdateWidget(FutureBuilder<T> oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.future != widget.future) {
      if (_activeCallbackIdentity != null) {
        _unsubscribe();
        _snapshot = _snapshot.inState(ConnectionState.none);
      }
      _subscribe();
    }
  }
复制代码


可以看到它是判断futrue是否是同一个对象来执行重绘的,所以我们只要提前将异步任务的函数赋值给一个变量,然后在FutureBuilder中使用这个变量即可,如下:


var _mFuture;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _mFuture = _future();
  }
 _future() async{
    ...
  }
FutureBuilder(
    future: _mFuture,
    ...
)
复制代码


有人提到直接将函数赋值是否可以达到同样的效果,比如:


_future() async{
    ...
  }
FutureBuilder(
    future: _future(),
    ...
)
复制代码

根据网友的总结,是不可以的。待验证。


目录
相关文章
|
1月前
Flutter 组件(二)文本 与 输入框组件
Flutter 组件(二)文本 与 输入框组件
120 0
|
1月前
|
容器
Flutter 组件(一)组件概述
Flutter 组件(一)组件概述
67 0
|
1月前
|
Dart 前端开发 开发工具
【Flutter前端技术开发专栏】Flutter入门指南:搭建开发环境与第一个应用
【4月更文挑战第30天】本文介绍了Flutter SDK的安装和配置过程,以及如何创建并运行第一个Flutter应用。首先确保安装了Dart SDK和Flutter SDK,支持macOS、Linux和Windows。安装完成后,设置环境变量,然后通过`flutter doctor`验证安装。接着,使用`flutter create`命令创建新项目,进入项目目录并运行`flutter run`启动应用。在`main.dart`中修改代码以自定义应用。Flutter支持热重载和DevTools调试。本文为Flutter初学者提供了快速入门的指导。
【Flutter前端技术开发专栏】Flutter入门指南:搭建开发环境与第一个应用
|
1月前
|
设计模式 JavaScript 前端开发
flutter组件封装技巧
工厂函数不会自动调用,需要手动调用
27 3
|
1月前
|
数据库 Android开发
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
|
1月前
|
Dart
Flutter 中优雅切换应用主题的组件
【Flutter】使用adaptive_theme组件优雅切换应用主题:封装MaterialApp,支持light/dark/system模式,自定义色彩,保存选择,含调试按钮。安装配置、设置主题、监听切换、自定义颜色、读取配置步骤详细。代码示例与学习路径推荐。[查看完整教程](https://flutter.ducafecat.com/blog/flutter-app-theme-switch)
Flutter 中优雅切换应用主题的组件
|
1月前
|
前端开发 搜索推荐 UED
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
【4月更文挑战第30天】探索Flutter的高级UI组件,如`TabBar`、`Drawer`、`BottomSheet`,提升应用体验和美观度。使用高级组件能节省开发时间,提供内置交互逻辑和优秀视觉效果。示例代码展示了如何实现底部导航栏、侧边导航和底部弹出菜单。同时,自定义组件允许个性化设计和功能扩展,但也带来性能优化和维护挑战。参考Flutter官方文档和教程,深入学习并有效利用这些组件。
【Flutter前端技术开发专栏】Flutter中的高级UI组件应用
|
9月前
|
人机交互
Flutter笔记 - ListTile组件及其应用
Flutter笔记 - ListTile组件及其应用
126 0
|
1月前
|
开发者 索引 容器
Flutter开发笔记:Flutter 布局相关组件
Flutter开发笔记:Flutter 布局相关组件
163 0
|
1月前
|
iOS开发
Flutter 组件(三)按钮类组件
Flutter 组件(三)按钮类组件
196 0