一、普通更新方式setState:
1、代码:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("----build MyApp");
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCount() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
print("----build MyHomePage");
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Count(_counter),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCount,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
class Count extends StatefulWidget {
final int counter;
Count(this.counter);
@override
_CountState createState() => _CountState();
}
class _CountState extends State<Count> {
@override
Widget build(BuildContext context) {
print("----build Count");
return Text(
'${widget.counter}',
style: Theme.of(context).textTheme.headline4,
);
}
}
2、控制台输出
首次安装运行输出:
点击加号计数按钮输出:
重复点击加号计数按钮输出:
**
二、 使用provider方式跨级更新数据(可减少子树中build()调用次数)**
1、引入库:
provider: ^4.3.2+3
推荐库地址:https://pub.dev/packages/provider
2、代码:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
/// Providers are above [MyApp] instead of inside it, so that tests
/// can use [MyApp] while mocking the providers
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Counter()),
],
child: const MyApp(),
),
);
}
/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool
// ignore: prefer_mixin
class Counter with ChangeNotifier, DiagnosticableTreeMixin {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
print("----build MyApp");
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
print("----build MyHomePage");
return Scaffold(
appBar: AppBar(
title: const Text('Example'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text('You have pushed the button this many times:'),
Count(),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<Counter>().increment(),
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
class Count extends StatelessWidget {
const Count({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
print("----build Count");
return Text('${context.watch<Counter>().count}',
style: Theme.of(context).textTheme.headline4);
}
}
3、控制台输出
刚安装运行控制台输出:
I/flutter (32756): ----build MyApp
I/flutter (32756): ----build MyHomePage
I/flutter (32756): ----build Count
点击计数按钮后控制台输出:
I/flutter (32756): ----build Count
再次点击计数按钮后控制台输出:
I/flutter (32756): ----build Count
如图(不停点击计数按钮只构建Count中的build()):
4、分析:
在页面构建的过程中,尽量提取Widget可增强程序的复用性、可读性,结合provider可实现在页面中执行setState时直接只构建最深层级的子Widget,中间层的Widget不执行build()