Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dart 颤振执行顺序:build和initState_Dart_Flutter - Fatal编程技术网

Dart 颤振执行顺序:build和initState

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”中初始化的变量添

我正在尝试创建一个首选项菜单,其中有三个设置(例如“通知”)与共享首选项一起存储。它们应用于SwitchListTiles

每次选择“我的设置”选项卡时,都会出现一个错误(I/flatter(22754):引发另一个异常:“package:flatter/src/material/switch\u list\u tile.dart”:失败的断言:第84行pos 15:“value!=null”:不正确。)仅出现一毫秒。之后,将显示正确的设置。当我没有向“ProfileState”中初始化的变量添加默认值时,就会发生这种情况。如果它们有一个默认值,错误就会消失,但在从默认值到共享首选项中的正确值的选项卡选择时,开关会“闪烁”

我的假设是loadSettings函数是在build方法之后执行的

我怎样才能解决这个问题?感谢您的帮助

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) {
   ...
   ...