Flutter局部刷新

在开发项目的时候,一个比较复杂的页面。如果setstate会触发build导致整个页面刷新。页面会闪烁。

有时候,往往需要刷新的只是其中一个很小的widget. 这个时候我们就需要局部刷新。
原理就是将需要刷新的widget单独提取为一个statefulwidget,然后再其内部调用setState方法来刷新。

可以用的框架有
Provider
Redux
或者直接StreamController + StreamBuilder
我使用过Provider与StreamBuilder的两种方法。
先说说Provider的方式:
首先创建Model

class FilterModel with ChangeNotifier {
  int _count = 0;
  bool _isOpen = false;
 
  int get value => _count;
  bool get isOpen => _isOpen;
 
  void increment() {
    _count++;
    notifyListeners();
  }
	
  void switchAction() {
    _isOpen = !_isOpen;
    notifiListeners();
  }
}

然后在App入口处使用Provider

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return  MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => CounterProvider()),,
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(),
        initialRoute: '/login',
        onGenerateRoute: Router.generateRoute,
      ),
    );
  }
}

然后在子页面中就可以引用Provider了。
引用的方式有:
Consumer, 监听某个Provider
Selector, 监听某个Provider中的某一个
Provider.of, 监听或刷新
context.watch(), 一方法使得widget能够监听泛型T上发生的改变。
context.read(),直接返回T,不会监听改变。
context.select<T, R>(R cb(T value)),允许widget只监听T上的一部分®。

Consumer的方式就不说了, 只要Provider中有一个值改变,就会触发刷新。
Selector指定刷新区域,原理是缓存了Widget, 如果值改变了就调用builder刷新, 否则使用cache的Widget

Selector<FilterModel, bool>(
  selector: (context, state) => state.isOpen,
  builder: (ctx, data, child) {
    return Switch(
      value: data,
      activeColor: Color(0xFF9168DA),
      onChanged: (bool val) {
        filterModel.switchAction();
      },
    );
  },
)

下面通过Builder是可以获取需要的值,就不需要再最外面声明很多变量,再需要的时候再声明,这是一个技巧。

Container(
  child: Builder(builder: (context) {
    final isOpen= context.select((FilterModel state) => state.isOpen);
    return Switch(
      value: isOpen,
      activeColor: Color(0xFF9168DA),
      onChanged: (val) {
        filterModel.switchAction();
      },
    );
  }),
)

注意,Provider是不能跨router使用的哦。 比如你在A页面引入Provider, 在B页面去获取,会报错哦。

在同一个页面,Provider.of(context), 这个context必须是子context, 不能与page的context为同一个,否则会报错!

不明白的可以交流。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值