【Flutter 问题系列第 10 篇】Flutter 使用 StatefulBuilder 组件实现局部刷新

这是【Flutter 问题系列第 10 篇】,如果觉得有用的话,欢迎关注专栏。

一:为什么需要局部刷新

我们知道 Flutter 刷新界面可以用 setState 方法,但这种方法会遍历每一个子 Widget 的 State.build 从而达到刷新的效果。

这不仅会增加性能上的开销,有时候界面和数据比较复杂时,也会因全界面刷新从而带来意料之外的问题,所以我们需要做局部刷新的处理。

在 Flutter 中局部刷新也可以用 GlobalKey 的方式,不过有说尽量少用全局 key 的方式,所以介绍一下官方提供的局部刷新组件 StatefulBuilder,接下来是博客正文。

二:StatefulBuilder 组件介绍

先附带上 StatefulBuilder 组件 的 官网链接 ,可自行查看官方例子。

1:举例说明全局刷新的弊端

声明两个 int 类型的变量 a 和 b ,默认初始值都为 1,如下代码所示(已省去部分无关代码)

Row(
	children: <Widget>[
      ElevatedButton(
        onPressed: () => setState(() => a++), // 点击的时候让 a 自增
        child: Text("我想只让 a 自增"),
      ),
      Builder(builder: (context) {
        b++;
        return ElevatedButton(child: Text("我想只让 b 自增"));
      }),
    ],
  ),
Row(
  children: <Widget>[
    Text("当前 a 的值:$a"),
    Text("当前 b 的值:$b"),
  ],
),

程序初始化后的结果如下图所示
在这里插入图片描述

目前这段代码会造成两个问题

  • 程序初始化的时候,当前 a 的值是 1,但 b 的值会是 2,因为界面第一次初始化的时候会走 Builder 组件中的 b++
  • 同样的问题,当点击让 a 自增的时候,界面全局刷新还是会走 Builder 组件中的 b++ ,所以当我们只想让 a 自增的时候,b 同时也在自增。

也许你会说,为什么不把 b++ 放到右边按钮的点击事件中,这样即使界面刷新,b 也不会自增。当然这是可以的,不过我们想说的是遇到这种类似的情况时,如何解决。

显然,这两种情况都不是我们想要的,接下来就用 StatefulBuilder 组件解决这个问题。

2:如何用 StatefulBuilder 组件实现局部刷新

步骤一

声明一个 StateSetter 的对象,StateSetter bSetter ,这里我命名为 bSetter。

步骤二

在需要刷新状态的组件中,用 StatefulBuilder 包括着,我们需要实现它的 builder 方法,并且将参数中的 setState 赋值给我们自己定义的 bSetter ,让状态知道局部刷新的是哪个组件。

StatefulBuilder(
  builder: (BuildContext context, StateSetter setState) {
    bSetter = setState;
    return Container(
      margin: EdgeInsets.symmetric(vertical: 5),
      child: Text("局部刷新中当前 b 的值:$b"),
    );
  },
),

步骤三

在执行事件的代码中,调用 bSetter 方法,通知界面去刷新被 bSetter 绑定了状态的组件中,完成局部刷新

如下代码所示

ElevatedButton(
  onPressed: () {
    b++;
    this.bSetter(() {});
  },
  child: Text("我想只让 b 自增"),
  style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.purple)),
)

动态演示图如下

在这里插入图片描述

  • 当我们去点击只让 a 自增的按钮时,a 自增的同时,并没有影响到 b
  • 当我们去点击只让 b 自增的按钮时,b 也完成了局部刷新

不过你可能发现了,当点击只让 b 自增按钮时,界面上 当前 b 的值 并没有随着刷新,这是为什么呢?

因为我们只用 StatefulBuilder 组件包括了局部刷新中当前 b 的值,bSetter 方法绑定了状态的也是这个组件,就像火影里只有和动物签订了契约的,才可以被召唤出来一样。

所以虽然 b 的值的确是增加了,但是界面并没有去刷新 当前 b 的值 这个组件,这也说明了局部刷新成功。

ok,关于用 StatefulBuilder 组件实现局部刷新就介绍到这里,希望可以帮到正在看博客的你。

你的问题得到解决了吗?欢迎在评论区留言。

赠人玫瑰,手有余香,如果觉得文章不错,希望可以给个一键三连,感谢。


结束语

Google 的 Flutter 越来越火,截止 2021年4月17日 GitHub 标星已达 86K,Flutter 毅然是一种趋势,所以作为前端开发者,没有理由不趁早去学习。

无论你是 Flutter 新手还是已经入门了,不妨先点个关注,后续我会将 Flutter 中的常用组件(含有源码分析、组件的用法及注意事项)以及可能遇到的问题写到 CSDN 博客中,希望自己学习的同时,也可以帮助更多的人。
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen Su

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值