【问题标题】:Data Persistence using shared preferences使用共享首选项的数据持久性
【发布时间】:2020-11-14 18:04:30
【问题描述】:

我是一名新手程序员,这是我第一次真正尝试编写应用程序。我希望编写一个应用程序,然后可以通过蓝牙远程触发,以便在紧急情况下向预设联系人发送短信。 但是,我坚持使用包共享首选项,我试图将联系人数据保存到应用程序以在重新启动期间使用。根据 Android Studio,我按照教程完成了没有严重错误的代码,但数据仍未保存。请相应地提出建议。

import 'package:contact_picker/contact_picker.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  return runApp(Whican());
}

class Whican extends StatefulWidget {
  @override
  _WhicanState createState() => _WhicanState();
}

class _WhicanState extends State<Whican> {
  final ContactPicker _contactPicker = new ContactPicker();
  Contact _contact;
  @override
  void initState() {
    getData();
  }

  getData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _contact = prefs.get(_contact.toString());
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(
            title: Center(child: const Text('WHICAN APP')),
            backgroundColor: Colors.deepOrangeAccent,
          ),
          drawer: Drawer(
            child: ListView(
              padding: EdgeInsets.zero,
              children: <Widget>[
                DrawerHeader(
                  decoration: BoxDecoration(color: Colors.orangeAccent),
                  child: Text(
                    'Settings',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 24,
                    ),
                  ),
                ),
                ListTile(
                  leading: Icon(Icons.message),
                  title: Text('Update Emergency Message'),
                ),
                ListTile(
                  leading: Icon(Icons.contacts),
                  title: Text('Update Emergency Contact'),
                  onTap: () async {
                    Contact contact = await _contactPicker.selectContact();
                    SharedPreferences prefs =
                        await SharedPreferences.getInstance();
                    setState(() {
                      _contact = contact;
                      prefs.setString(_contact.toString(), _contact.toString());
                    });
                    print(contact); //TODO: Remove this
                  },
                ),
                ListTile(
                  leading: Icon(Icons.bluetooth),
                  title: Text('Connect Bluetooth'),
                ),
                ListTile(
                  leading: Icon(Icons.help),
                  title: Text('Help'),
                ),
                ListTile(
                  leading: Icon(Icons.feedback),
                  title: Text('Feedback'),
                ),
              ],
            ),
          ),
          body: Row(children: <Widget>[
            Expanded(
              child: Card(
                color: Colors.orangeAccent,
                child: Container(
                  alignment: Alignment.center,
                  child: Column(
                    children: <Widget>[
                      Icon(
                        Icons.contacts,
                        size: 60.0,
                      ),
                      Text(_contact.toString()),
                    ],
                  ),
                ),
              ),
            ),
          ]),
        ));
  }
}

【问题讨论】:

  • 为什么不把这个SharedPreferences prefs = await SharedPreferences.getInstance();放在一个地方而不是调用两次呢?并且在setState((){})之外也调用prefs.setString(...)

标签: flutter dart flutter-dependencies


【解决方案1】:

根据我的调查,第一个问题发生在 initState 中的 getData 方法被调用时。在这里,您的字段 _contact 始终为空。所以实际上_contact = prefs.get(_contact.toString());这行代码每次都返回null。

此外,您不能简单地以这种方式保存联系人对象:prefs.setString(_contact.toString(), _contact.toString()); 此代码将在键“'Contact' 实例”下的共享首选项中保存字符串值“'Contact' 实例”。如果您想将联系人对象保存在共享首选项中,您可以考虑将其转换为 JSON,然后将 JSON 保存为字符串值。请注意,这只是可能的解决方案之一,也许您可​​以在共享首选项中保存联系人 ID 或其他内容,并使用它通过 ContactPicker 获取联系。但是,保存已解析的联系人代码可能如下所示:

Contact contact = await _contactPicker.selectContact();
String contactJson = parseContactToJsonString(contact);
prefs.setString("savedContact", contactJson);  

这是加载代码:

String contactJson = prefs.get("savedContact");
_contact = convertJsonToContact(contactJson);

当然 parseContactToJsonString 和 convertJsonToContact 是你应该自己实现的方法。例如,您可以在此处找到有关 JSON 序列化的信息:https://flutter.dev/docs/development/data-and-backend/json

【讨论】:

    猜你喜欢
    • 2021-09-19
    • 2014-08-08
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多