任何一个App都会有username这种需要全局使用的数据
任何一个App都会有userdata数据发生变化相关UI的同步更新的需求
本节我们来使用Provider解决第二个问题,
请先阅读Flutter Provider入门(一)
首先改造一下MyApp类
将包裹AppWidget的Provider更改为ChangeNotifierProvider
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<TitleText>(
builder: (context) => TitleText(),
child: MaterialApp(
title: 'flutter demo',
home: const MyHomePage(),
),
);
}
}
改造一下title.dart文件
import 'package:flutter/foundation.dart';
class TitleText with ChangeNotifier{
String _title = '12345';
String get title => _title;
void set(String title) {
_title = title;
notifyListeners();
}
}
运行程序,得到一下错误提示:
════════ Exception caught by foundation library ════════════════════════════════════════════════════
The following assertion was thrown while dispatching notifications for TitleText:
setState() or markNeedsBuild() called during build.
意思就是我们在更新UI的时候又触发UI更改,问题来自以下代码
class MyHomePage extends StatelessWidget {
const MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final titleText = Provider.of<TitleText>(context);
/// 在build中设置set会导致build的调用,从而引起死循环
titleText.set('我是共享文字');
return Scaffold(
appBar: AppBar(title: Text('first')),
body: Center(
child: FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context){
return SecondRoute();
}));
},
child: Text(titleText.title)
)
),
//floatingActionButton : const IncrementCounterButton()
);
}
}
删除
titleText.set('我是共享文字');
运行代码,可以看到点击SecondRoute中的更新按钮,
两个页面的按钮文字都同步发生了变化。
续
让我们来研究一下官方的Demo
并对诸如ChangeNotifierProvider从何处来,用法为何做一个深入
Flutter Provider入门(三)