Dart 颤振执行顺序:build和initState
我正在尝试创建一个首选项菜单,其中有三个设置(例如“通知”)与共享首选项一起存储。它们应用于SwitchListTiles 每次选择“我的设置”选项卡时,都会出现一个错误(I/flatter(22754):引发另一个异常:“package:flatter/src/material/switch\u list\u tile.dart”:失败的断言:第84行pos 15:“value!=null”:不正确。)仅出现一毫秒。之后,将显示正确的设置。当我没有向“ProfileState”中初始化的变量添加默认值时,就会发生这种情况。如果它们有一个默认值,错误就会消失,但在从默认值到共享首选项中的正确值的选项卡选择时,开关会“闪烁” 我的假设是loadSettings函数是在build方法之后执行的 我怎样才能解决这个问题?感谢您的帮助Dart 颤振执行顺序:build和initState,dart,flutter,Dart,Flutter,我正在尝试创建一个首选项菜单,其中有三个设置(例如“通知”)与共享首选项一起存储。它们应用于SwitchListTiles 每次选择“我的设置”选项卡时,都会出现一个错误(I/flatter(22754):引发另一个异常:“package:flatter/src/material/switch\u list\u tile.dart”:失败的断言:第84行pos 15:“value!=null”:不正确。)仅出现一毫秒。之后,将显示正确的设置。当我没有向“ProfileState”中初始化的变量添
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Profile extends StatefulWidget {
@override
ProfileState createState() {
return new ProfileState();
}
}
class ProfileState extends State<Profile> {
bool notifications;
bool trackHistory;
bool instantOrders;
@override
void initState() {
super.initState();
loadSettings();
}
//load settings
loadSettings() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
notifications = (prefs.getBool('notifications') ?? true);
trackHistory = (prefs.getBool('trackHistory') ?? true);
instantOrders = (prefs.getBool('instantOrders') ?? false);
});
}
//set settings
setSettings() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool('notifications', notifications);
prefs.setBool('trackHistory', trackHistory);
prefs.setBool('instantOrders', instantOrders);
}
@override
Widget build(BuildContext context) {
return new ListView(
children: <Widget>[
new Row(
children: <Widget>[
new Container(
padding: new EdgeInsets.fromLTRB(20.0, 20.0, 0.0, 8.0),
child: new Text("General", style: new TextStyle(color: Colors.black54)),
)
],
),
new SwitchListTile(
title: const Text('Receive Notifications'),
activeColor: Colors.brown,
value: notifications,
onChanged: (bool value) {
setState(() {
notifications = value;
setSettings();
});
},
secondary: const Icon(Icons.notifications, color: Colors.brown),
),
new SwitchListTile(
title: const Text('Track History of Orders'),
activeColor: Colors.brown,
value: trackHistory,
onChanged: (bool value) {
setState((){
trackHistory = value;
setSettings();
});
},
secondary: const Icon(Icons.history, color: Colors.brown,),
),
new SwitchListTile(
title: const Text('Force instant Orders'),
activeColor: Colors.brown,
value: instantOrders,
onChanged: (bool value) {
setState((){
instantOrders = value;
setSettings();
});
},
secondary: const Icon(Icons.fast_forward, color: Colors.brown),
),
new Divider(
height: 10.0,
),
new Container(
padding: EdgeInsets.all(32.0),
child: new Center(
child: new Column(
children: <Widget>[
new TextField(
)
],
),
),
),
new Divider(
height: 10.0,
),
new Row(
children: <Widget>[
new Container(
padding: new EdgeInsets.fromLTRB(20.0, 20.0, 0.0, 20.0),
child: new Text("License Information", style: new TextStyle(color: Colors.black54)),
)
],
),
new Container(
padding: new EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0) ,
child: new RichText(
text: new TextSpan(
text: "With confirming our terms and conditions you accept full usage of your personal data. Yikes!",
style: new TextStyle(color: Colors.black)
)
)
)
]
);
}
}
导入“包装:颤振/材料.省道”;
导入“package:shared_preferences/shared_preferences.dart”;
类配置文件扩展了StatefulWidget{
@凌驾
ProfileState createState(){
返回新的ProfileState();
}
}
类ProfileState扩展了状态{
bool通知;
布尔轨迹历史;
布尔瞬变器;
@凌驾
void initState(){
super.initState();
加载设置();
}
//负载设置
loadSettings()异步{
SharedReferences prefs=等待SharedReferences.getInstance();
设置状态(){
通知=(prefs.getBool('notifications')??true);
trackHistory=(prefs.getBool('trackHistory')??true);
instantOrders=(prefs.getBool('instantOrders')??false);
});
}
//设置设置
setSettings()异步{
SharedReferences prefs=等待SharedReferences.getInstance();
prefs.setBool(“通知”,通知);
prefs.setBool('trackHistory',trackHistory);
prefs.setBool('实例化器',实例化器);
}
@凌驾
小部件构建(构建上下文){
返回新的ListView(
儿童:[
新行(
儿童:[
新容器(
填充:来自LTRB(20.0,20.0,0.0,8.0)的新边缘设置,
子项:新文本(“常规”,样式:新文本样式(颜色:Colors.black54)),
)
],
),
新SwitchListTile(
标题:常量文本(“接收通知”),
activeColor:Colors.brown,
价值:通知,
一旦更改:(布尔值){
设置状态(){
通知=值;
设置设置();
});
},
次要:常量图标(Icons.notifications,颜色:Colors.brown),
),
新SwitchListTile(
标题:const Text(“订单跟踪历史记录”),
activeColor:Colors.brown,
价值:轨道历史,
一旦更改:(布尔值){
设置状态(){
trackHistory=值;
设置设置();
});
},
次要:常量图标(Icons.history,颜色:Colors.brown,),
),
新SwitchListTile(
标题:常量文本(“强制即时命令”),
activeColor:Colors.brown,
值:实例化器,
一旦更改:(布尔值){
设置状态(){
瞬变器=值;
设置设置();
});
},
次要:常量图标(图标。快进,颜色:颜色。棕色),
),
新分隔器(
身高:10.0,
),
新容器(
填充:边缘设置。全部(32.0),
孩子:新中心(
子:新列(
儿童:[
新文本字段(
)
],
),
),
),
新分隔器(
身高:10.0,
),
新行(
儿童:[
新容器(
填充:来自LTRB(20.0,20.0,0.0,20.0)的新边缘设置,
子项:新文本(“许可证信息”,样式:新文本样式(颜色:Colors.black54)),
)
],
),
新容器(
填充:来自LTRB(20.0,0.0,20.0,20.0,20.0)的新边缘设置,
孩子:新富文本(
text:newtextspan(
文本:“确认我们的条款和条件后,您接受您的个人数据的充分使用。Yikes!”,
样式:新文本样式(颜色:Colors.black)
)
)
)
]
);
}
}
编辑
我试图用Darek解决方案中推荐的FutureBuilder解决这个问题。最初的错误现在解决了,但现在我面临另一个不便。每次点击一个明显可见的开关时,该选项卡就会完全自行构建。此外,开关不再平稳运行。在应用程序启动时,你也可以很快看到等待消息,但这并不漂亮
下面是代码中的新类:
class ProfileState extends State<Profile> {
bool notifications;
bool trackHistory;
bool instantOrders;
SharedPreferences prefs;
@override
void initState() {
super.initState();
loadSettings();
}
//load settings
Future<String> loadSettings() async {
prefs = await SharedPreferences.getInstance();
notifications= (prefs.getBool('notifications') ?? true);
trackHistory = (prefs.getBool('trackHistory') ?? true);
instantOrders= (prefs.getBool('instantOrders') ?? true);
}
//set settings
setSettings() async {
prefs.setBool('notifications', notifications);
prefs.setBool('trackHistory', trackHistory);
prefs.setBool('instantOrders', instantOrders);
}
@override
Widget build(BuildContext context) {
var profileBuilder = new FutureBuilder(
future: loadSettings(), // a Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return new Text('No preferences');
case ConnectionState.waiting:
return new Text('Loading preferences');
case ConnectionState.done:
if (snapshot.hasError)
return new Text('Error: ');
else
return new Column(
children: <Widget>[
new Row(
children: <Widget>[
new Container(
padding: new EdgeInsets.fromLTRB(20.0, 20.0, 0.0, 8.0),
child: new Text("General", style: new TextStyle(color: Colors.black54)),
)
],
),
new SwitchListTile(
title: const Text('Receive Notifications'),
activeColor: Colors.brown,
value: notifications,
onChanged: (bool value) {
setState(() {
notifications = value;
setSettings();
});
},
secondary: const Icon(Icons.notifications, color: Colors.brown),
),
new SwitchListTile(
title: const Text('Track History of Orders'),
activeColor: Colors.brown,
value: trackHistory,
onChanged: (bool value) {
setState((){
trackHistory = value;
setSettings();
});
},
secondary: const Icon(Icons.history, color: Colors.brown,),
),
new SwitchListTile(
title: const Text('Force instant Orders'),
activeColor: Colors.brown,
value: instantOrders,
onChanged: (bool value) {
setState((){
instantOrders = value;
setSettings();
});
},
secondary: const Icon(Icons.fast_forward, color: Colors.brown),
),
new Divider(
height: 10.0,
),
new Row(
children: <Widget>[
new Container(
padding: new EdgeInsets.fromLTRB(20.0, 20.0, 0.0, 20.0),
child: new Text("License Information", style: new TextStyle(color: Colors.black54)),
)
],
),
new Container(
padding: new EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0) ,
child: new RichText(
text: new TextSpan(
text: "With confirming our terms and conditions you accept full usage of your personal data. Yikes!",
style: new TextStyle(color: Colors.black)
)
)
)
]
);
}
},
);
return new Scaffold(
body: profileBuilder,
);
}
}
类ProfileState扩展状态{
bool通知;
布尔轨迹历史;
布尔瞬变器;
共享引用优先权;
@凌驾
void initState(){
super.initState();
加载设置();
}
//负载设置
Future loadSettings()异步{
prefs=等待SharedReferences.getInstance();
通知=(prefs.getBool('notifications')??true);
trackHistory=(prefs.getBool('trackHistory')??true);
instantOrders=(prefs.getBool('instantOrders')??true);
}
//设置设置
setSettings()异步{
prefs.setBool(“通知”,通知);
prefs.setBool('trackHistory',trackHistory);
prefs.setBool('实例化器',实例化器);
}
@凌驾
小部件构建(构建上下文){
var profileBuilder=新的FutureBuilder(
future:loadSettings(),//future或null
生成器:(BuildContext上下文,异步快照){
交换机(快照.连接状态){
案例连接状态。无:
返回新文本(“无首选项”);
new FutureBuilder(
future: _calculation, // a Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none: return new Text('Press button to start');
case ConnectionState.waiting: return new Text('Awaiting result...');
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return new Text('Result: ${snapshot.data}');
}
},
)
class ProfileState extends State<Profile> {
bool notifications;
bool trackHistory;
bool instantOrders;
SharedPreferences prefs;
Future<String> loadSettingsFuture; // <-Add this
@override
void initState() {
super.initState();
loadSettingsFuture = loadSettings();// <- Change This
}
...
...
...
@override
Widget build(BuildContext context) {
var profileBuilder = new FutureBuilder(
future: loadSettingsFuture, // <-- Change this
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
...
...