【问题标题】:Flutter: How to read preferences at Widget startup?Flutter:如何在 Widget 启动时读取首选项?
【发布时间】:2018-06-25 11:18:17
【问题描述】:

我一直在尝试阅读 Widget 启动时的首选项,但无法找到解决方案。 我希望在 TextField 中显示用户名(他们可以更改)并将其存储在首选项中,以便在他们返回页面时立即显示。

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller;
  :
  :
  Future<Null> storeName(String name) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString("name", name);
  }

  @override
  initState() async {
    super.initState();
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _controller = new TextEditingController(text: prefs.getString("name"));
  }

  @override
  Widget build(BuildContext context) {
  :
  :
  return new TextField(
               decoration: new InputDecoration(
                 hintText: "Name (optional)",
               ),
               onChanged: (String str) {
                 setState(() {
                   _name = str;
                   storeName(str);
                 });
               },
               controller: _controller,
             )
  }
}

我得到了在 initState() 上使用异步的想法:
flutter timing problems on stateful widget after API call
但是异步似乎在启动时导致了这个错误:

'package:flutter/src/widgets/framework.dart': Failed assertion: line 967 pos 12: 
'_debugLifecycleState == _StateLifecycle.created': is not true.

我查找了 FutureBuilder 的示例,但似乎找不到与我正在尝试做的类似的任何示例。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    我建议不要在 initState() 上使用异步。但是您可以通过将 SharedPreferences 包装在另一个函数中并将其声明为异步来以不同的方式执行此操作。

    我修改了你的代码。请检查这是否有效。非常感谢。

    修改代码:

    class _MyHomePageState extends State<MyHomePage> {
      TextEditingController _controller;
      String _name;
    
      Future<Null> getSharedPrefs() async {
        SharedPreferences prefs = await SharedPreferences.getInstance();
        _name = prefs.getString("name");
        setState(() {
          _controller = new TextEditingController(text: _name);
        });
      }
    
      @override
      void initState() {
        super.initState();
        _name = "";
        getSharedPrefs();  
      }
    
      @override
      Widget build(BuildContext context) {
    
        return new TextField(
                     decoration: new InputDecoration(
                       hintText: "Name (optional)",
                     ),
                     onChanged: (String str) {
                       setState(() {
                         _name = str;
                         storeName(str);
                     });
                   },
                   controller: _controller,
        );
      }
    }
    

    如果这有帮助,请告诉我。 谢谢。

    【讨论】:

    • 感谢@Mahi 的帮助-您的解决方案给了我答案。 (我修改了您的代码以添加 setState() 以使其充分发挥作用)。
    【解决方案2】:

    initState() 是一个同步函数,您不能标记async,因为async 将该函数转换为异步函数。

    以下代码有助于在加载时加载共享首选项值,并用于更新小部件。

    @override
      void initState() {
        super.initState();
        SharedPreferences.getInstance().then((prefValue) => {
          setState(() {
            _name = prefValue.getString('name')?? "";
            _controller = new TextEditingController(text: _name);
          })
        });
      }
    

    【讨论】:

    • 这比接受的答案更干净和推荐。但是,在外部方法上编写逻辑并在 initState 中调用该方法更干净,就像上面的答案一样。
    • 这不会等待首选项加载。
    • 如果您之前创建了 TextEditingController,那么您可以使用 _controller.text = _name;
    【解决方案3】:

    在应用级别进行。

    SharedPreferences prefs;
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      prefs = await SharedPreferences.getInstance();
    
      // Rest of your code...
    }
    

    【讨论】:

      【解决方案4】:

      你也可以 User Timer 或 Future.delayed

      首先为 SharedPreference 创建您的方法

      Future getId() async {
           SharedPreferences prefs = await SharedPreferences.getInstance();
      id = prefs.getString("id");
        }
      

      然后在你的 initMethod 中

      @override
        void initState() {
          getId();
          Timer(Duration(microseconds: 250), () {
            _controller = new TextEditingController(text: id);
          });
          super.initState();
        }
      

      【讨论】:

        猜你喜欢
        • 2018-10-02
        • 1970-01-01
        • 2018-10-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多