Dart 保存和加载,共享首选项

Dart 保存和加载,共享首选项,dart,flutter,Dart,Flutter,然后我保存它并退出应用程序。当我重新启动应用程序时,它会显示30而不是35的值。但如果我使用+1进行编辑,它会直接跳到36,这样我就知道值保存了,但在第一次启动时没有正确显示。之后,添加值可以正常工作。有人能帮我吗?我找不到这样做的方法。也许我应该在保存功能中输入默认值,以防不存在任何已保存的文件?谢谢你帮我保存和加载一个double列表的代码,因为我觉得我做得不好。再次感谢 这是我做的。(我可以在initState中调用任何异步函数,因此我调用了一个外部函数)。但是我得到了一个错误:“NoSu

然后我保存它并退出应用程序。当我重新启动应用程序时,它会显示30而不是35的值。但如果我使用+1进行编辑,它会直接跳到36,这样我就知道值保存了,但在第一次启动时没有正确显示。之后,添加值可以正常工作。有人能帮我吗?我找不到这样做的方法。也许我应该在保存功能中输入默认值,以防不存在任何已保存的文件?谢谢你帮我保存和加载一个double列表的代码,因为我觉得我做得不好。再次感谢

这是我做的。(我可以在initState中调用任何异步函数,因此我调用了一个外部函数)。但是我得到了一个错误:“NoSuchMethodError:方法”[]”被调用为null。 收件人:空 已尝试呼叫:

这是我的脚手架

I/flutter ( 9290): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 9290): The following RangeError was thrown building SettingsPage(dirty, dependencies: [MediaQuery], state:
I/flutter ( 9290): _SettingsPageState#c0ade):
I/flutter ( 9290): RangeError (index): Invalid value: Valid value range is empty: 0
I/flutter ( 9290): When the exception was thrown, this was the stack:
I/flutter ( 9290): #0      List.[] (dart:core-patch/growable_array.dart:145:60)
I/flutter ( 9290): #1      _SettingsPageState.build (package:my_fitness_tools/pages/settings_page.dart:175:45)
I/flutter ( 9290): #2      StatefulElement.build (package:flutter/src/widgets/framework.dart:3825:27)
I/flutter ( 9290): #3      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3739:15)
I/flutter ( 9290): #4      Element.rebuild (package:flutter/src/widgets/framework.dart:3565:5)
I/flutter ( 9290): #5      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3722:5)
I/flutter ( 9290): #6      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3864:11)
I/flutter ( 9290): #7      ComponentElement.mount (package:flutter/src/widgets/framework.dart:3717:5)
I/flutter ( 9290): #8      Element.inflateWidget (package:flutter/src/widgets/framework.dart:2961:14)
I/flutter ( 9290): #9      Element.updateChild (package:flutter/src/widgets/framework.dart:2764:12)
I/flutter ( 9290): #10     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4876:14)
I/flutter ( 9290): #11     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2961:14)
I/flutter ( 9290): #12     Element.updateChild (package:flutter/src/widgets/framework.dart:2764:12)
脚手架(
appBar:新的appBar(
背景色:Options.selectedTheme.primaryColorDark,
标题:对,
标题:文本(“设置”),
),
抽屉:drawerap(),
正文:
新堆栈(
儿童:[
新容器(
装饰:新盒子装饰(
图片:新装饰图片(
图片:新资产图像(“资产/背景/Sfondo.jpg”),
适合:BoxFit.fill),
),
ListView(//垂直ListView
儿童:[
//帕吉纳河的奥格蒂河。
大小盒子(
身高:10.0,
),
标题设置(“计时器”),
容器(
高度:MediaQuery.of(context).size.height,
子:ListView(//水平ListView
收缩膜:对,
物理:ClampingScrollPhysics(),
滚动方向:轴水平,
儿童:[
timer列(timersList[0],0),//第175行
timerColumn(TimerList[1],1),
timerColumn(TimerList[2],2),
timer列(timersList[3],3),
timerColumn(TimerList[4],4),
timer列(timersList[5],5),
],
),
),
],
)
编辑列表timersList=[0,0,0,0,0,0]修复了这个问题。 但是我有一个问题。如果我现在想在另一个文件中使用这些值。我已经为加载创建了相同的函数。但是我得到了这个错误。
声明所有内容和函数都是一样的,但为什么它希望是静态的,而以前的文件没有这样做?

这几乎肯定与执行顺序有关。您需要在代码中寻找尚未显示的答案

  • 创建的小部件状态
  • [30.0等分配给
    timersValueList
  • initState
    已调用,它可能会调用
  • 调用了
    LoadSharedReferences
    ,但挂起等待
    getInstance
    ,允许
  • 框架调用
    build
    -显示当前值(30)
  • getInstance
    完成,因此
    LoadSharedReferences
    继续将[35.0等赋值给
    TimerValueList
  • 在您进行更新之前,不会通知小部件其状态已更改
  • LoadSharedReferences
    末尾添加对
    setState
    的调用,以通知框架更改

    Scaffold(
              appBar: new AppBar(
                backgroundColor: Options.selectedTheme.primaryColorDark,
                centerTitle: true,
                title: Text("Settings"),
              ),
              drawer: DrawerApp(),
              body:
              new Stack(
                  children: <Widget>[
                new Container(
                  decoration: new BoxDecoration(
                      image: new DecorationImage(
                          image: new AssetImage("assets/backgrounds/Sfondo.jpg"),
                          fit: BoxFit.fill)),
                ),
                ListView( // vertical listview
                  children: <Widget>[
                    //Inizio oggetti in ordine verticale della pagina.
                    SizedBox(
                      height: 10.0,
                    ),
                    titleSettings("Timers"),
                    Container(
                      height: MediaQuery.of(context).size.height,
                      child: ListView( // horizontal Listview
                        shrinkWrap: true,
                        physics: ClampingScrollPhysics(),
                        scrollDirection: Axis.horizontal,
                        children: <Widget>[
                          timerColumn(timersList[0], 0), // line 175
                          timerColumn(timersList[1], 1),
                          timerColumn(timersList[2], 2),
                          timerColumn(timersList[3], 3),
                          timerColumn(timersList[4], 4),
                          timerColumn(timersList[5], 5),
                        ],
                      ),
                    ),
                  ],
                )
    

    您需要在
    setState
    中分配给
    timersList
    ,以便框架知道您已经更改了状态!这将导致它重新生成小部件。请注意,在
    构建
    中,您必须处理
    timersList
    为null的问题。为null表示您仍在等待事情发生,so应该呈现一个占位符。

    我理解你的意思。这真的很有意义。但是,我如何才能让它首先分配SharedReferences中加载的值,如果不存在默认值?非常感谢你的帮助。谢谢。我尝试了一些方法。如果你能给我一些帮助,我将非常感谢。谢谢。“警告:初始值设定项的右侧无权访问此项。”。"因此,你不能用常数或静态的东西以外的任何东西来初始化
    rimanenza1
    。你不能用本身无法初始化的东西来初始化它。请看下面的答案:现在使用这里显示的“欺骗”来消除处理未来的需要。它工作得很好。当然,你不想被欺骗o真正的长时间运行的东西,如主进程中的http,但将共享pref读入内存效果很好。
    class _SettingsPageState extends State<SettingsPage> {
      List<double> timersList;
    
      @override initState()  {
        super.initState();
        callLoad();
      }
      Future callLoad() async {
        timersList = await loadTimers();
      }
    
      void saveTimers(List<double> timersList) async {
        List<String> convertedTimerValues = timersList.map((i) => i.toString()).toList();
        SharedPreferences prefs = await SharedPreferences.getInstance();
        await prefs.setStringList('TimerList', convertedTimerValues);
      }
    
      Future<List<double>> loadTimers() async {
        List<double> defaultTimersList = [30.0, 60.0, 90.0, 120.0, 150.0, 180.0];
        List<double> savedTimerList;
        SharedPreferences prefs = await SharedPreferences.getInstance();
        List<String> myList =  prefs.getStringList('TimerList');
        if (myList == null ){
          return defaultTimersList;
        } else{
          savedTimerList = myList.map((i)=> double.parse(i)).toList();
          return savedTimerList;
        }
      }
    
    I/flutter ( 9290): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
    I/flutter ( 9290): The following RangeError was thrown building SettingsPage(dirty, dependencies: [MediaQuery], state:
    I/flutter ( 9290): _SettingsPageState#c0ade):
    I/flutter ( 9290): RangeError (index): Invalid value: Valid value range is empty: 0
    I/flutter ( 9290): When the exception was thrown, this was the stack:
    I/flutter ( 9290): #0      List.[] (dart:core-patch/growable_array.dart:145:60)
    I/flutter ( 9290): #1      _SettingsPageState.build (package:my_fitness_tools/pages/settings_page.dart:175:45)
    I/flutter ( 9290): #2      StatefulElement.build (package:flutter/src/widgets/framework.dart:3825:27)
    I/flutter ( 9290): #3      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3739:15)
    I/flutter ( 9290): #4      Element.rebuild (package:flutter/src/widgets/framework.dart:3565:5)
    I/flutter ( 9290): #5      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:3722:5)
    I/flutter ( 9290): #6      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3864:11)
    I/flutter ( 9290): #7      ComponentElement.mount (package:flutter/src/widgets/framework.dart:3717:5)
    I/flutter ( 9290): #8      Element.inflateWidget (package:flutter/src/widgets/framework.dart:2961:14)
    I/flutter ( 9290): #9      Element.updateChild (package:flutter/src/widgets/framework.dart:2764:12)
    I/flutter ( 9290): #10     SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:4876:14)
    I/flutter ( 9290): #11     Element.inflateWidget (package:flutter/src/widgets/framework.dart:2961:14)
    I/flutter ( 9290): #12     Element.updateChild (package:flutter/src/widgets/framework.dart:2764:12)
    
    Scaffold(
              appBar: new AppBar(
                backgroundColor: Options.selectedTheme.primaryColorDark,
                centerTitle: true,
                title: Text("Settings"),
              ),
              drawer: DrawerApp(),
              body:
              new Stack(
                  children: <Widget>[
                new Container(
                  decoration: new BoxDecoration(
                      image: new DecorationImage(
                          image: new AssetImage("assets/backgrounds/Sfondo.jpg"),
                          fit: BoxFit.fill)),
                ),
                ListView( // vertical listview
                  children: <Widget>[
                    //Inizio oggetti in ordine verticale della pagina.
                    SizedBox(
                      height: 10.0,
                    ),
                    titleSettings("Timers"),
                    Container(
                      height: MediaQuery.of(context).size.height,
                      child: ListView( // horizontal Listview
                        shrinkWrap: true,
                        physics: ClampingScrollPhysics(),
                        scrollDirection: Axis.horizontal,
                        children: <Widget>[
                          timerColumn(timersList[0], 0), // line 175
                          timerColumn(timersList[1], 1),
                          timerColumn(timersList[2], 2),
                          timerColumn(timersList[3], 3),
                          timerColumn(timersList[4], 4),
                          timerColumn(timersList[5], 5),
                        ],
                      ),
                    ),
                  ],
                )
    
      void loadSharedPreferences() async {
        SharedPreferences prefs = await SharedPreferences.getInstance();
        List<String> myList = prefs.getStringList('mylist') ?? ['30', '60', '90'];
        List<double> myOriginalList = myList.map((i) => double.parse(i)).toList();
        setState(() {
          timersValuesList = myOriginalList;
        });
      }
    
    class _SettingsPageState extends State<SettingsPage> {
      List<double> timersList;
    
      @override
      initState() {
        super.initState();
        loadTimers();
      }
    
      saveTimers(List<double> timersList) async {
        List<String> convertedTimerValues = timersList.map((i) => '$i').toList();
        SharedPreferences prefs = await SharedPreferences.getInstance();
        prefs.setStringList('TimerList', convertedTimerValues);
      }
    
      loadTimers() async {
        SharedPreferences prefs = await SharedPreferences.getInstance();
        List<String> myList = prefs.getStringList('TimerList');
        setState(() {
          timersList = (myList == null)
              ? [30.0, 60.0, 90.0, 120.0, 150.0, 180.0]
              : myList.map((i) => double.parse(i)).toList();
        });
      }
    
      @override
      Widget build(BuildContext context) {
        if (timersList == null) return Center(child: CircularProgressIndicator());
        return Whatever(/* Fill me in with the normal page*/);
      }
    }