首页 文章

Flutter:如何将用户创建的对象存储在本地存储中并将其检索到ListView中

提问于
浏览
0

我正在Flutter中重新创建我的应用程序Call Manager,我很难存储对象并将它们检索到列表中 . 使用SharedPreferences和GSON适用于完整的Android应用程序,但由于在Flutter中不存在GSON,在我看来,将onjects存储为JSON数据是可行的方法 .

流程应如下所示:用户在AddNewCall屏幕上添加新呼叫 . 这包括姓名,电话号码和可选说明' When the user clicks the '保存'按钮,从这些字段中的文本创建呼叫对象 . 该对象被编码为如下字符串: String jsonData = json.encode(newCallObject); 使用 getApplicationDocumentsDirectory() 将调用JSON数据保存到应用程序的本地存储中 . 用户将被带回主屏幕,其中JSON文件将在 initState() 方法中异步加载到应用程序中 . JSON数据被解码并添加到ListView我遇到的问题是,当JSON数据被添加到文件是第3步时,它将如下所示: {sampleData}{sampleData} 而不是被 [] 包围,作为数组 . 因此,应用程序在读取文件时会出现问题 . 到目前为止,我的解决方案是将文件的内容解析为数组,在} {之间插入一个下划线,并将生成的String拆分为String类型的数组 . 它看起来像这样:

String jsonCalls = await file.readAsString();
jsonCalls = jsonCalls.replaceAll('}{', '}_{');
List<String> temp = jsonCalls.split('_');

所以现在我得到一个包含JSON字符串的数组,但我仍然无法访问每个JSON字符串中的值 . 我正在采取的整个方法似乎过于复杂 . 必须有一个更好的方法,但我已经谷歌搜索疯狂,没有发现任何东西 . 你们能帮助我吗?

谢谢!

1 回答

  • 0

    以下是一些建议

    • Flutter使用plugin支持共享首选项,因此Android应该会感到熟悉 .

    • initState 仅在StatefulWidget第一次初始化时调用,因此可能不是一个期望重新加载更改信息的好地方

    • 考虑将您的工作状态保存在内存中,例如在 List<Call> 中,您可以随时添加新的呼叫 .

    • 当您将此 List 序列化为json时,它将按预期包装在括号中 . 编写整个列表,覆盖以前的版本 .

    • 使用后备存储(文件或共享首选项)作为应用程序使用之间的持久性,因此在启动时读取一次,并在每次在内存中修改时写入 . 应用程序运行时,内存中的副本是主副本 .

    这应该减少了将json破解为字符串的需要 .

    也许是这样的:

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Call Manager',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      List<Call> calls = [];
    
      @override
      void initState() {
        super.initState();
        load();
      }
    
      load() async {
        // initially populate calls by getting last value from shared preferences and parsing it
      }
    
      persist() async {
        // encode calls as json and write to share prefs
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('Calls'),
          ),
          body: new ListView(
            scrollDirection: Axis.horizontal,
            children: calls
                .map((call) => new ListTile(
                      title: new Text(call.phoneNumber),
                    ))
                .toList(),
          ),
          floatingActionButton: new FloatingActionButton(
            onPressed: () {
              Navigator.push<Call>(
                context,
                new MaterialPageRoute(
                  builder: (context) => new SecondPage(),
                ),
              ).then((newCall) {
                if (newCall != null) {
                  setState(() {
                    calls.add(newCall);
                  });
                  persist();
                }
              });
            },
            tooltip: 'New',
            child: new Icon(Icons.add),
          ),
        );
      }
    }
    

相关问题