android - Flutter - 在每次应用重启后保持变量的值

标签 android flutter dart asynchronous sharedpreferences

在我的一页上,我希望我的用户从一个变量 (codeDialog) 的默认文本开始,然后我希望他们更改该文本,之后他们写的文本将是我的新的默认文本。遗憾的是我无法让它工作。

现在,当我重新启动应用程序并打开该屏幕时,它会重置为 null。我认为这是因为初始化变量(为空),但我找不到解决该问题的方法。任何的想法? 谢谢。

所有这些都在 statefulwidget 的状态类中:

void initState() {
    super.initState();
    print(codeDialog);
    isFirstTime().then((isFirstTime) {
      isFirstTime ? defaultText() : readFromShared();
    });
    setText();
    print(codeDialog);
    _textEditingController = new TextEditingController(text: codeDialog);
  }
Future<bool> isFirstTime() async {
    final prefs = await SharedPreferences.getInstance();
    var isFirstTime = prefs.getBool('first_time');
    if (isFirstTime != null && !isFirstTime) {
      prefs.setBool('first_time', false);
      return false;
    } else {
      prefs.setBool('first_time', false);
      return true;
    }
  }
  static String codeDialog;
  void defaultText(){
    print("first time");
    codeDialog="This is what i want my default variable to be when my app first opened.";
  }

  void readFromShared() async{
    print("not first");
    final prefs = await SharedPreferences.getInstance();
    codeDialog = prefs.getString('sharedmessage');
  }
  void setText() async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString('sharedmessage', codeDialog);
  }

然后我有 AlertDialog,它可以工作并保存数据。

AlertDialog(
            scrollable: true,
            contentPadding: EdgeInsets.fromLTRB(20, 20, 20, 0),
            content: Column(
              children: [
                Container(
                  height: maxLines * 10.0,
                  child: TextField(
                    controller:  new TextEditingController(text: codeDialog),//_textEditingController,
                    maxLines: maxLines,
                    onChanged: (value){
                      setState(() {
                        valueText=value;
                      });
                    },
                    decoration: InputDecoration(
                      hintText: "Text here",
                    ),
                  ),
                ),
              ],
            ),
            actions: [
              TextButton(
                  onPressed: Navigator.of(context).pop, child: Text("Cancel")),
              TextButton(
                  onPressed: () {
                    setState(() {
                      Navigator.pop(context);
                      codeDialog = valueText;
                      print(codeDialog);
                      setText();
                    });
                  },
                  child: Text("Save"))
            ],
          )

编辑:同样值得注意的是可能会看到这个问题的人。如果您不更改 TextField 的值并提交它(由于某种原因在应用程序重新启动后),该值将更改为 null(我认为是因为字符串没有变化)。您可以通过添加 if(value==null) 来修复它,如果它不为空则保存它。

最佳答案

你必须使用包 shared preference .我将使用源代码中的示例进行编辑

我会使用 FutureBuilder 而不是 initstate,因为它更干净:

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

class SavedPreference extends StatefulWidget {
  SavedPreference({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _SavedPreference createState() => _SavedPreference();
}

class _SavedPreference extends State<SavedPreference> {
  TextEditingController _textEditingController;
  String valueText;

  void initState() {
    super.initState();
  }

  Future<String> _getSharedValue() async {
    const defaultText =
        "This is what i want my default variable to be when my app first opened.";
    String ret;
    var prefs = await SharedPreferences.getInstance();
    bool isFirstTime = prefs.getBool('firstTime');
    print(isFirstTime);

    ret =
        (isFirstTime == null || isFirstTime == true) ? defaultText : prefs.getString('sharedmessage');
    print(ret);

    _textEditingController = new TextEditingController(text: ret);
    return ret;
  }

  String codeDialog;

  void setText() async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString('sharedmessage', valueText);
    prefs.setBool('firstTime', false);
  }

  @override
  Widget build(BuildContext context) {
    int maxLines = 10;
    return Container(
        child: FutureBuilder(
            future: _getSharedValue(),
            builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
              print(snapshot.data);
              if (snapshot.hasData) {
                return TextButton(
                    child: Text(snapshot.data),
                    onPressed: () async => await showDialog(
                        context: context,
                        builder: (context) => new AlertDialog(
                              scrollable: true,
                              contentPadding:
                                  EdgeInsets.fromLTRB(20, 20, 20, 0),
                              content: Column(
                                children: [
                                  Container(
                                    height: maxLines * 10.0,
                                    child: TextField(
                                      controller: new TextEditingController(
                                          text: codeDialog),
                                      maxLines: maxLines,
                                      onChanged: (value) {
                                        valueText = value;
                                      },
                                      decoration: InputDecoration(
                                        hintText: "Text here",
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                              actions: [
                                TextButton(
                                    onPressed: Navigator.of(context).pop,
                                    child: Text("Cancel")),
                                TextButton(
                                    onPressed: () {
                                      setState(() {
                                        Navigator.pop(context);
                                        codeDialog = valueText;
                                        print(codeDialog);
                                        setText();
                                      });
                                    },
                                    child: Text("Save"))
                              ],
                            )));
              } else
                return CircularProgressIndicator();
            }));
  }
}

您的问题是 initState 没有正确等待 await SharedPreferences.getInstance(); 的结果(我试图在 initState 中修复它并浪费了大量时间)

关于android - Flutter - 在每次应用重启后保持变量的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66426801/

相关文章:

google-closure - 使用Google Closure Library for Google DART吗?

Android 集群和标记点击

java - 无法使用 findViewById 找到 mpandroidchart

android - 处理程序 postDelayed 按配置延迟更长的时间

java - 使用 API key 解析 JSON

json - 使用云函数时,来自 firestore 的时间戳被转换为 Map

android - E/flutter (8084): [ERROR:flutter/lib/ui/ui_dart_state. cc(157)]未处理的异常:SocketException:操作系统错误:连接被拒绝

dart - 使用 Dart 编辑器中的标志启动 Dartium

flutter - 如何从flutter中计算widget的剩余大小?

android - 如何在 flutter 的 View 之间发送和接收参数