简体   繁体   English

颤抖的sharedpreferences没有从第一次建立起就设置状态

[英]flutter sharedpreferences not setting state from first built

I am trying to have values saved in sharedPreferences loaded when the app loads. 我正在尝试在加载应用程序时加载保存在sharedPreferences中的值。 But it gives me always the static list of double declared [0,0,0,0,0,0] at first built. 但是,它始终为我提供了首次构建时双重声明为[0,0,0,0,0,0]的静态列表。 whenever i touch something that set the state it changes to my correct values. 每当我触摸设置状态的东西时,它就会更改为正确的值。 I don't even need that static list I am just declaring it because dart is asking me. 我什至不需要声明该静态列表,因为dart在问我。 I want the default list if there is nothing already saved in there, otherwise I want the sharedpreferences saved list. 如果其中没有任何内容,我想要默认列表,否则,我想要sharedpreferences保存的列表。 here is my code. 这是我的代码。

@override initState()  {
    super.initState();
    callLoad();
  }

  callLoad() async{
    List<double> list = await loadTimers();
    setState((){
      timersList = list;
    });
  }

  Future<List<double>> loadTimers() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    List<String> myList =  prefs.getStringList('TimerList');
    List<double> defaultTimersList = [30.0, 60.0, 90.0, 120.0, 150.0, 180.0];
    List<double> savedTimerList;
      if (myList == null ){
        return defaultTimersList;
      } else{
        savedTimerList = myList.map((i)=> double.parse(i)).toList();
        return savedTimerList;
      }
  }

  static List<double> timersList = [0,0,0,0,0,0];

  double timeRemaining1 = timersList[0];
  double timeRemaining2 = timersList[1];
  double timeRemaining3 = timersList[2];
  double timeRemaining4 = timersList[3];
  double timeRemaining5 = timersList[4];
  double timeRemaining6 = timersList[5];

I tried this way too but it is the same. 我也尝试过这种方法,但是是一样的。

@override initState()  {
    super.initState();
    loadTimers();
  }


  loadTimers() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    List<String> myList =  prefs.getStringList('TimerList');
    List<double> defaultTimersList = [30.0, 60.0, 90.0, 120.0, 150.0, 180.0];
    List<double> savedTimerList;
      if (myList == null ){
        setState(() {
          timersList = defaultTimersList;

        });
      } else{
        savedTimerList = myList.map((i)=> double.parse(i)).toList();
         setState(() {
           timersList = savedTimerList;
         });
      }
  }

  static List<double> timersList = [0,0,0,0,0,0];

  double timeRemaining1 = timersList[0];
  double timeRemaining2 = timersList[1];
  double timeRemaining3 = timersList[2];
  double timeRemaining4 = timersList[3];
  double timeRemaining5 = timersList[4];
  double timeRemaining6 = timersList[5];

Thank you 谢谢

Edit with little app showing the problem. 使用显示问题的小应用程序进行编辑。

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo chokuns 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;

  @override initState()  {
    super.initState();
    callLoad();
  }

  callLoad() async{
    List<double> list = await loadTimers();
    setState((){
      timersList = list;
    });
  }

  Future<List<double>> loadTimers() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    List<String> myList =  prefs.getStringList('TimerList');
    List<double> defaultTimersList = [30.0, 60.0, 90.0, 120.0, 150.0, 180.0];
    List<double> savedTimerList;
    if (myList == null ){
      return defaultTimersList;
    } else{
      savedTimerList = myList.map((i)=> double.parse(i)).toList();
      return savedTimerList;
    }
  }

  static List<double> timersList = [0,0,0,0,0,0];

  double timeRemaining1 = timersList[0];
  double timeRemaining2 = timersList[1];
  double timeRemaining3 = timersList[2];
  double timeRemaining4 = timersList[3];
  double timeRemaining5 = timersList[4];
  double timeRemaining6 = timersList[5];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button \nthis many times:',
              textAlign: TextAlign.center,
            ),
            Text(
              '$timeRemaining1', //showing here $timersList it shows correct values
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
    );
  }
}

Change callLoad to: callLoad更改为:

  callLoad() async{
    List<double> list = await loadTimers();
    setState((){
      timersList = list;
      timeRemaining1 = timersList[0];
      timeRemaining2 = timersList[1];
      timeRemaining3 = timersList[2];
      timeRemaining4 = timersList[3];
      timeRemaining5 = timersList[4];
      timeRemaining6 = timersList[5];
    });
  }

Basically, Dart is passing by reference of object. 基本上,Dart通过引用传递对象。 So, Your idea is correct. 因此,您的想法是正确的。 But, I will explain why it does not work. 但是,我将解释为什么它不起作用。 It is caused by List<double> list = await loadTimers(); 这是由List<double> list = await loadTimers(); because it is new object. 因为它是新对象。 Below code shows TrueTrue . 下面的代码显示TrueTrue But, If you change //isSameList = identical(timersList, timersList2); 但是,如果您更改//isSameList = identical(timersList, timersList2); to isSameList = identical(timersList, timersList2); isSameList = identical(timersList, timersList2); , It shows FalseTrue . ,它显示FalseTrue You have to restart it. 您必须重新启动它。

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  SharedPreferences prefs;
  static List<double> timersList = [0,0,0,0,0,0];
  double timeRemaining1;
  List<double> timersList2;
  bool isSameList;
  bool isSameValue;

  @override initState()  {
    super.initState();
    initValues();
    callLoad();
  }

  void initValues()
  {
    timeRemaining1 = timersList[0];
    timersList2 = timersList;
    isSameList = identical(timersList, timersList2);
    isSameValue = identical(timersList[0], timeRemaining1);
  }

  Future<void> callLoad() async{
    prefs = await SharedPreferences.getInstance();
    List<double> list = await loadTimers();
    setState((){
      timersList = list;
      //isSameList = identical(timersList, timersList2);
    });
  }

  List<double> loadTimers() {
    List<String> myList =  prefs.getStringList('TimerList');
    List<double> defaultTimersList = [30.0, 60.0, 90.0, 120.0, 150.0, 180.0];
    List<double> savedTimerList;
    if (myList == null ){
      return defaultTimersList;
    } else{
      savedTimerList = myList.map((i)=> double.parse(i)).toList();
      return savedTimerList;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button \nthis many times:',
              textAlign: TextAlign.center,
            ),
            Text(
              '$isSameList'+'$isSameValue', //showing here $timersList it shows correct values
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
    );
  }

Finally, I could know how to use pass by reference for the list. 最后,我可以知道如何使用pass by reference列表。

timersList.setAll(0, list);

It shows the result well. 它很好地显示了结果。 But, timeRemaining1 still can not be showed becuase it can not keep the reference . 但是,由于无法保留reference ,因此仍无法显示timeRemaining1 So, I think you can handle it with List object as above way. 因此,我认为您可以按上述方式使用List对象进行处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM