在Flutter中提供了几种局部刷新的方式,这里简单演示一下Selector
的使用,Selector只会在监听的数据改变时候去刷新所包裹的UI,这样就为一个对象中不同内容的更改做了区分。
这里实现一个简单的功能作为说明,以下定义一个数据类,里面包含两个变量 _count
和 _age
。定义页面中包含两个Text
和两个RaisedButton
。每个按钮分别会更改一个值显示在Text
上面。当其中一个值进行更新当时候不会触发另外一个Text
的刷新,更不会触发整个UI的刷新。
ps:之所以定义在一个数据类里面定义两个变量。是为了测试对整个对象中的单个变量更新会不会触发其它变量的监听。就好比一个User
对象中的年龄改变了,但是并不会导致姓名也一起刷新。
代码如下:
/// Provider的局部刷新
/// 上次的通用版本在数值改变的时候会触发整个Provider包裹的builder函数
(可以使用child进行渲染UI,用法可以查看第一篇文章https://blog.csdn.net/Mr_Tony/article/details/111414413),
在性能上会有一点问题
/// 通过Provider提供的局部刷新功能可以减少这个性能损耗,简单示例代码如下:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class Count with ChangeNotifier {
int _count = 1;
int _age = 1;
int get count => _count;
int get age => _age;
void increment() {
_count++;
notifyListeners();
}
void incrementAge() {
_age++;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: Text('Material App Bar'),
),
body: Center(
child: Container(
child: Home(),
),
),
),
);
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Count>(
create: (_) => Count(),
builder: (context, child) {
print('YM---->重新build');
return Column(
children: [
Selector<Count,int>(//两个对象对应输入(Count)和输出(int)
builder: (context,count,int){//这个count是selector中返回的数据
print('build111111');
return Text('数值:$count');
},
selector: (_,count){
return count.count;
},
),
RaisedButton(
onPressed: () {
context.read<Count>().increment();
// context.read<Count>().incrementAge();
},
child: Text('计数'),
),
Selector<Count,int>(
builder: (context,count,int){
print('build22222222');
return Text('数值age:$count');
},
selector: (_,count){
return count.age;
},
),
RaisedButton(
onPressed: () {
context.read<Count>().incrementAge();
},
child: Text('计数age'),
),
],
);
},
);
}
}