【问题标题】:What is the correct way to get the value which has been stored using sharedPreferences to widget?获取使用 sharedPreferences 存储到小部件的值的正确方法是什么?
【发布时间】:2020-03-20 13:41:51
【问题描述】:

将使用sharedPreferences 存储的值获取到小部件的正确方法是什么?

页面A

 @override
  void initState() {
    super.initState();
    sharedPreferences = SampleSharedPreferences().getData();
    sharedPreferences.then((onValue) {
      name = onValue.name;  // I debug this line, I can see the value
    });
  }

     @override
      Widget build(BuildContext context) {
        return Scaffold(
            body: SingleChildScrollView(
                child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Padding(
              child: Text(
                name,
                style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
              ),
              padding: const EdgeInsets.only(top: 14.0, left: 14.0),
            ),
              ....

错误

A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 269 pos 10: 'data != null'

我猜是因为小部件在SharedPreferences 被调用之前首先调用?正确的写法是什么?

SampleSharedPreferences

class SampleSharedPreferences {

  static const NAME = "user_name";

  void store(ABC abc) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString(NAME, name);
  }

  Future<ABC> getUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    ABC abc = new ABC();
    abc.name = prefs.getString(USER_NAME);
    return abc;
  }
}

【问题讨论】:

  • 是的,小部件是在 name 属性出现之前构建的。当 SharedPreferences 数据使用非空名称属性重建您的小部件时,请使用 FutureBuilder 或调用 setState()

标签: flutter dart widget sharedpreferences


【解决方案1】:

SharedPrefernces 需要一些时间来加载,所以使用FutureBuilder

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Padding(
              child: FutureBuilder(
                future: getUser, // a previously-obtained Future<String> or null
                builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
                  switch (snapshot.connectionState) {
                    case ConnectionState.none:
                      return Text('Press button to start.');
                    case ConnectionState.active:
                    case ConnectionState.waiting:
                      return CircularProgressIndicator();
                    case ConnectionState.done:
                      if (snapshot.hasError)
                        return Text('Error: ${snapshot.error}');
                      return Text(
                        snapshot.data,
                        style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                      );
                  }
                  return null; // unreachable
                },
              ),
              padding: const EdgeInsets.only(top: 14.0, left: 14.0),
            ),
          ],
        ),
      ),
    );
  }

【讨论】:

  • getUser是调用sharedPreferences的函数吗?
【解决方案2】:

您的问题是简单的 sharedPreferences 需要一些时间来获取保存在其中的值,当它获取值构建函数时已经调用了它,因此它会给您A non-null String must be provided to a Text widget. 这个错误。

解决方案: 所以要么尝试初始化你的 Srting name=""

或检查,

Text(
  name!=null? name:'',
  style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
  ),

每当 sharepref 准备好您的 String 时,尝试调用 setSate,

 sharepref .then((onValue) {
      setState(() {
        mUserInfo = onValue;
      });
    }

【讨论】:

  • 我应该把setState()放在哪里?
猜你喜欢
  • 1970-01-01
  • 2020-06-20
  • 2018-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多