首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用setState还是FutureBuilder的InitState?哪种方法更适合在Flutter中显示数据库中的数据?

在Flutter中,setStateFutureBuilder都可以用来处理异步数据加载,但它们的使用场景和目的有所不同。

setState

setState是Flutter中最基本的用于更新UI的方法。它通常用于状态管理,当你需要在Widget内部改变状态并且让UI重新构建时使用。

优势:

  • 简单易用,适合小型应用或者状态变化不复杂的场景。
  • 可以直接在Widget内部管理状态。

类型:

  • 同步更新状态。

应用场景:

  • 当数据更新不频繁,或者数据可以直接从Widget内部获取时。

问题与解决方案:

  • 如果在initState中使用setState来加载数据库数据,可能会导致不必要的UI重建,因为initState只会在Widget创建时调用一次。
  • 解决方案是使用异步方法加载数据,并在数据加载完成后使用setState更新状态。

FutureBuilder

FutureBuilder是Flutter提供的一个Widget,用于处理异步操作的结果,并根据结果来构建UI。

优势:

  • 专门用于处理异步操作,如网络请求或数据库查询。
  • 可以根据异步操作的状态(等待、成功、失败)来构建不同的UI。

类型:

  • 异步更新状态。

应用场景:

  • 当需要处理异步数据加载,尤其是数据来源是网络请求或数据库查询时。

问题与解决方案:

  • 如果使用FutureBuilder不当,可能会导致UI显示不一致或错误的状态。
  • 解决方案是确保FutureBuilderfuture属性指向一个确定的异步操作,并且在builder函数中正确处理各种状态。

示例代码

使用setState

代码语言:txt
复制
class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  List<Data> _data = [];

  @override
  void initState() {
    super.initState();
    _loadData();
  }

  Future<void> _loadData() async {
    List<Data> data = await fetchDataFromDatabase();
    setState(() {
      _data = data;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: _data.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(_data[index].title),
        );
      },
    );
  }
}

使用FutureBuilder

代码语言:txt
复制
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Data>>(
      future: fetchDataFromDatabase(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(child: CircularProgressIndicator());
        } else if (snapshot.hasError) {
          return Center(child: Text('Error: ${snapshot.error}'));
        } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
          return Center(child: Text('No data found'));
        } else {
          return ListView.builder(
            itemCount: snapshot.data!.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(snapshot.data![index].title),
              );
            },
          );
        }
      },
    );
  }
}

结论

对于从数据库加载数据的场景,FutureBuilder通常是更好的选择,因为它能够更好地处理异步操作的状态,并且可以避免不必要的UI重建。然而,如果你的应用逻辑简单,且数据更新不频繁,使用setState也是可行的。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

FLutter异步加载组件FutureBuilder

FutureBuilder 在实际开发中,进入一个页面后执行网络请求加载数据并显示是非常普遍的,这时候我们一般会显示loading直到加载完成显示正常页面。...在flutter中我们可以在initState中发起异步请求,然后将请求结果赋值给data,并setState刷新页面,在build中可以这样实现 if(data == null){ return...snapshot的connectionState表示异步任务的状态,如果是ConnectionState.done表示任务完成,这时候通过snapshot.hasError来区分是出错(显示错误)还是正常完成...(显示数据);否则就表示任务在执行中(显示laoding)。...所以我们只要提前将异步任务的函数赋值给一个变量,然后在FutureBuilder中使用这个变量即可,如下: var _mFuture; @override void initState()

2.2K30

【 源码之间 - Flutter 】 FutureBuilder 使用

一、前言: 主要就是请求网络api,返回数据,展业界面。根据不同的状态显示不同的界面。...FutureBuilder的使用 先定义异步任务和当前页码,在使用FutureBuilder进行构造组件。全代码见文尾。...get方法方便使用 final ConnectionState connectionState; # 连接状态 final T data; # 数据 final Object error; #...,也就是源码中的这里 可以看出回调中会将异步返回的数据放在_snapshot这个瓶子里,并setState 这样_snapshot更新后,会重新执行build方法,又会回调外界的_builderList...父组件刷新时的_FutureBuilderState的行为 在点击加号时,更新异步方法,获取下一页数据,然后父组件执行setState void _doAdd() { setState(() {

1.1K20
  • FutureBuilder源码分析

    关于 FutureBuilder 的使用,我在之前的公众号文章中有写过, 如果没看过的可以跳转:Flutter FutureBuilder 异步UI神器....= null), super(key: key); 构造函数很简单,上一篇文章也说过,主要就是三个参数: •future:是我们的异步请求,该异步请求必须不能在 build 方法中初始化!...initState() 接着是初始化方法: @override void initState() { super.initState(); _snapshot = AsyncSnapshot<T...总结 Future 的状态无非三种: 1.未开始2.进行中3.已完成 其中 已完成 又分为两种: 1.有数据2.有异常 其实可以看到,FutureBuilder 大体上的思路就是对 Future 状态的封装...在 Flutter 中,我们可以通过查看源码来获取很多的灵感,因为 Flutter 的 注释写的简直不要太到位!

    84920

    Flutter | 定义一个通用的多功能网络请求 Widget

    不过,后续还是会每周最少更新两篇的! 那说起网络请求的控件,我们首先是不是会想起 FutureBuilder? FutureBuilder 给我们封装好了网络请求中的各种状态。...我们在网络请求中添加了一个 Loading,而且需要一个 BuildContext。 我们都知道,是不能在 initState() 方法中去使用这个 BuildContext 的。...请求数据并显示 Loading 但是,这里也有一个问题: 我们在最开始定义网络请求工具类的时候,每一个网络请求都是一个方法,而每个方法中都有或者没有参数。...第一帧回调 中来调用该网络请求了,这样一举两得: 既不用在使用该控件的时候调用方法,又避免了 Loading 使用 BuildContext 报错的问题。...然后在 ConnectionState.done 中判断是否存在数据,如果有的话,就显示传进来的 Widget。 如果返回错误,则返回错误的 Widget。

    1.7K31

    Flutter | 事件循环,Future

    正文 在 Dart 中,没有多线程的概念,所谓的异步操作全部都是在一个线程里面执行的, 并且不会造成卡顿的原因就是事件循环(Event Loop), 如下图所示,在程序的运行过程中,会有两个事件...,就会自动调用下面的 build 函数, initialData:初始值,在 future 没完成的时候可以暂时使用该值,该值会放在 AsyncSnapshot 的 data 中,在 future...FutureBuilder 的作用就是根据 future 的状态来判断当前页面需要显示哪些 widiget,例如 future 在等待的时候显示加载框,完成之后显示内容等。...在日常开发中,StreamBuilder 还是挺实用的,这次我们用 StreamBuilder 来做一个小游戏,先看效果: 从上面的动画来看,可以将其分为三个部分,第一个部分则是底部的键盘,第二部分就是向下落的题目...Stream,并且创建了一个动画,在 initState 中,监听动画和输入事件,动画结束则表示没有答对题,直接重置,并扣分,收到输入事件之后则 计算结果是否真确,然后重置,并且加分 reset 方法中用于生产题目和

    4.3K10

    Flutter Widgets 之 FutureBuilder

    展示异步任务状态 当有一个Future(异步)任务需要展示给用户时,可以使用FutureBuilder控件来完成,比如向服务器发送数据成功时显示成功提示: var _future = Future.delayed...builder是FutureBuilder的构建函数,在这里可以判断状态及数据显示不同的UI, ConnectionState的状态包含四种:none、waiting、active、done,但我们只需要关注...ListView加载网络数据 FutureBuilder还有一个比较常用的场景:网络加载数据并列表展示,这是一个非常常见的功能,在网络请求过程中显示loading,请求失败时显示失败UI,成功时显示成功...通过上面的示例说明FutureBuilder控件极大的简化了异步任务相关显示的控件,不再需要开发者自己维护各种状态以及更新时调用`State.setState`。...... } FutureBuilder( future: _future(), ... ) 上面的方式是不相等的,是错误的用法,可以将_future方法赋值给变量: var _mFuture

    1.3K40

    Flutter混编工程之通讯之路

    这个系列开始,我们将从「能用的Flutter」到「可用的Flutter」的迁移过程来讲解如何在实际项目中更好的使用Flutter,下面是第一篇。 对于混编工程来说,最常用的需求就是双端的数据通信。...提供了Flutter调用原生方法的能力。...中,图片数据使用Uint8List来进行传递。...首先,我们在Flutter中构建这样一个列表,用于展示一个信息List,信息的来源是原生侧,所以,在Flutter界面的initState中,我们创建一个名为stringCodecDemo的BasicMessageChannel...❞ 另外,不管是在Flutter中,还是在原生代码中,都是可以通过Channel来向对方通信的,以BasicMessageChannel为例,原生和Flutter侧,都可以调用send函数来发送消息,也都可以设置

    1.9K20

    Flutter自制插件之r_scan二维码&条形码扫描(支持文件、url、内存、相机)

    介绍 二维码作为信息的载体,广泛应用于我们生活的方方面面,例如:使用支付宝支付,二维码加好友,二维码推广等等,能举例的例子多不胜数,而如果你的应用支持二维码的扫描,用户和体验将会翻倍的增长,如果你是应用的开发者...项目地址:https://github.com/rhymelph/r_scan 使用 你可以在pub.dev网站上面搜索r_scan即可找到该插件,添加下面代码到pubspec.yaml文件 dependencies...();; 如果你在main()方法下获取可用相机,请使用下面代码 List rScanCameras; void main() async { WidgetsFlutterBinding.ensureInitialized...(已弃用)基于PlatformView使用相机扫描二维码/条形码 import 'package:flutter/material.dart'; import 'package:permission_handler...打开闪光灯/获取闪光灯状态 使用RScanController类的实例直接调用 //关闭闪光灯 await _controller.setFlashMode(false); //打开闪光灯 await

    2.1K20

    【Flutter 实战】文件系统目录

    老孟导读:Flutter 中获取文件路径,我们都知道使用 path_provider,但对其目录对含义不是很清楚,此文介绍 Android、iOS 系统的文件目录,不同场景下建议使用的目录。...不同的平台对应的文件系统是不同的,比如文件路径,因此 Flutter 中获取文件路径需要原生支持,原生端通过 MethodChannel 传递文件路径到 Flutter,如果没有特殊的需求,推荐大家使用...下面从 Android 和 iOS 平台的角度介绍其文件路径,最后给出路径使用的建议以及使用过程中需要注意的事项。 Android 文件存储 Android 文件存储分为内部存储和外部存储。...存储的空间有限,此目录数据随时可能被系统清除,也可以通过 设置 中的 清除数据 可以清除此目录数据。...() { super.initState(); setState(() { _tempDirectory = getTemporaryDirectory(); _

    3K10

    Flutter 面试知识点集锦

    Zone Dart 中可通过 Zone 表示指定代码执行的环境,类似一个沙盒概念,在 Flutter 中 C++ 运行 Dart 也是在 _runMainZoned 内执行 runZoned 方法启动...didChangeDependencies() 在 initState() 之后调用,当 State 对象的依赖关系发生变化时,该方法被调用,初始化时也会调用。...image ---- 通过 StreamBuilder 和 FutureBuilder 我们可以快速使用 Stream 和 Future 快速构建我们的异步控件: 《Flutter完整开发实战详解(十一...+ Surface 等实现的,大致原理就是: 使用了类似副屏显示的技术,VirtualDisplay 类代表一个虚拟显示器,调用 DisplayManager 的 createVirtualDisplay...() 方法,将虚拟显示器的内容渲染在一个 Surface 控件上,然后将 Surface 的 id 通知给 Dart,让 engine 绘制时,在内存中找到对应的 Surface 画面内存数据,然后绘制出来

    5.2K61

    Flutter 中的 Shimmer 动画效果

    处理向用户传递信息正在加载的一种主流方法是在不准确的加载物质类型的形状上显示带有微光动画的铬色调。 在在这篇博客中,我们将探索 Flutter 中的 Shimmer 动画效果。...它演示了应用程序从服务器或本地数据库加载信息。有多种方法可以显示这种效果。在这种情况下,我们通常会在加载信息后对与第一个小部件完全相似的小部件进行动画处理。...此演示视频展示了如何在颤动中创建微光动画效果。它展示了如何在 Flutter应用程序中使用shimmer包来实现微光动画效果。...它显示代码何时成功运行,然后显示内容正在从虚拟数据加载是带有持续时间的微光动画效果,然后加载完成然后内容将显示在您的设备上。...,微光停止,所有数据将显示在您的屏幕上。

    6.2K20

    Flutter 刷新页面:通过下拉刷新提升用户体验

    无论选择哪种方法,目标都是确保在触发刷新操作时,应用程序的状态能够反映新数据,而不会导致用户界面的中断或者不一致。...当在 Flutter 中实现下拉刷新,使用 Provider,我们需要通过一个 provider 来暴露一个方法来刷新数据,然后在 onRefresh 回调函数中调用该方法。...在复杂的 Flutter 应用程序中拉动刷新 在更复杂的 Flutter 应用程序中,下拉刷新可能和多个状态层和数据源有交互。在这种场景中,实现一个能够处理复杂性的有强大状态管理的解决方案至关重要。...当处理复杂的数据和状态时,考虑使用流 streams 或者 FutureBUilder 挂件来更新 UI,当新数据反应可用时。这保证在应用程序当前状态, UI 还是同步的,即使数据被拉取和更新。...FutureBuilder 通过 _handleRefresh 方法拉取最新的数据来构建列表。

    33510
    领券