Flutter 性能优化2
2019-07-16 本文已影响0人
果果人8023
仅适用于一次数据更新,例如:在initState加载异步数据
flutter在布局中,我们除了无状态小部件还有有状态小部件,每次需要修改有状态小部件时都需要setState,setState以后,StatefulWidget的build方法就会被调用,然而在build中,有些小部件跟修改的参数并没有什么关系,它以为在build中,也会跟着build的重新构建跟随这构建,这个时候我们可以使用FutureBuilder
正常代码
import 'package:flutter/material.dart';
class StatePage extends StatefulWidget {
@override
StatePageState createState() => new StatePageState();
}
class StatePageState extends State<StatePage> {
int count;
@override
Widget build(BuildContext context) {
print('test StatePageState build');
return Scaffold(
appBar: AppBar(
title: Text('statePage', style: TextStyle(fontSize: 16)),
centerTitle: true,
),
body: Align(
child: Column(
children: <Widget>[
Text("this count:$count"),
RaisedButton(
child: Text('add'),
onPressed: add,
),
],
),
));
}
void add() {
setState(() {
count += 1;
});
}
}
每次RaisedButton 点击调用add更新count值后,build方法都会被重新构建。
当使用FutureBuilder以后。
import 'package:flutter/material.dart';
class StatePage extends StatefulWidget {
@override
StatePageState createState() => new StatePageState();
}
class StatePageState extends State<StatePage> {
@override
Widget build(BuildContext context) {
print('test StatePageState build');
return Scaffold(
appBar: AppBar(
title: Text('statPage', style: TextStyle(fontSize: 16)),
centerTitle: true,
),
body: Align(
child: Column(
children: <Widget>[
FutureBuilder(
future: countFuture(),
builder: (context, snapshot) {
print('test FutureBuilder builder');
return Text("this number:${snapshot.data}");
},
),
],
),
));
}
Future countFuture() async {
await Future.delayed(Duration(seconds: 2));
return Future.value(1000);
}
}
第一次构建的时候,会打印两个内容
I/flutter (28440): test StatePageState build
I/flutter (28440): test FutureBuilder builder
然后FutureBuilder 会执行countFuture()方法,单countFuture返回future以后,页面会重新调用FutureBuilder中的builder重新构建builder中的小部件,而不会在执行StatePageState中的build方法
第二次打印内容
//第一次
I/flutter (28440): test StatePageState build
I/flutter (28440): test FutureBuilder builder
//第二次
I/flutter (28440): test FutureBuilder builder
原理:FutureBuilder内部继承了StatefulWidget,当widget.future 有值的时候执行 setState更新FutureBuilder视图
void _subscribe() {
...
widget.future.then<void>((T data) {
if (_activeCallbackIdentity == callbackIdentity) {
setState(() {
_snapshot = AsyncSnapshot<T>.withData(ConnectionState.done, data);
});
}
}, onError: (Object error) {
if (_activeCallbackIdentity == callbackIdentity) {
setState(() {
_snapshot = AsyncSnapshot<T>.withError(ConnectionState.done, error);
});
}
});
...
}