json - 在 Flutter 中将 Json 数组转换为 List<Object>

标签 json flutter dart

我是 Flutter 和 Dart 的新手,我一直在努力保存共享首选项中的值,以便在我的应用程序重新启动时使用。我已经成功存储了变量,但我还需要存储对象列表。我知道由于共享首选项只接受字符串列表,因此我需要将对象列表转换为 JSON 数组,并在重新启动应用程序时检索此列表并将其再次转换为对象列表。

我能够将对象列表编码为 JSON,我得到了这样的结果:

[{name: Rent, amount: 250}, {name: Insurance, amount: 105}]

我通过以下功能实现了这一点:
  void SaveLists(key, value) async { //where value is a List<Object>
    final prefs = await SharedPreferences.getInstance();
    List<dynamic> json_list = (value.map((i) => i.toJson())).toList();
    prefs.setStringList(key, json_list); //this line causes the error
    print('$json_list');
  }

列表 json_list 包含上面显示的 JSON 数组。但是,当我尝试使用 prefs.setStringList(key, json_list); 将其存储在共享首选项中时我收到以下错误:
Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'List<String>'

现在,假设我以某种方式成功地将它存储在共享首选项中,当使用 prefs.getString('key') 调用时如何将 JSON 数组转换回列表?

如果您需要查看类(class),请看这里:
import 'dart:convert';
class Random_expenses {

 String name;
 double amount;

 Random_expenses({this.name, this.amount});

 Random_expenses.fromJson(Map<String, dynamic> json)
     : this.name = json['name'],
       this.amount = json['amount'];

 Map<String, dynamic> toJson() =>
     {'name': this.name, 'amount': this.amount};
}

最佳答案

您可以在下面复制粘贴运行完整代码
您可以保存 List<RandomExpenses>作为带有 randomExpensesToJson(value) 的 json 字符串
您可以获得List<RandomExpenses>randomExpensesFromJson(keyString)
代码片段

List<RandomExpenses> randomExpensesFromJson(String str) =>
    List<RandomExpenses>.from(
        json.decode(str).map((x) => RandomExpenses.fromJson(x)));

String randomExpensesToJson(List<RandomExpenses> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
...
void saveData(String key, List<RandomExpenses> value) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString(key, randomExpensesToJson(value));
  }

Future<List<RandomExpenses>> getData(String key) async {
  final prefs = await SharedPreferences.getInstance();
  String keyString = prefs.getString(key);
  return Future.value(randomExpensesFromJson(keyString));
}
...
await saveData("key", randomExpensesList);
List<RandomExpenses> list = await getData("key");

print('${list[0].name} ${list[0].amount}');
print('${list[1].name} ${list[1].amount}');

输出
I/flutter (24879): Rent 250
I/flutter (24879): Insurance 105

完整代码
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

List<RandomExpenses> randomExpensesFromJson(String str) =>
    List<RandomExpenses>.from(
        json.decode(str).map((x) => RandomExpenses.fromJson(x)));

String randomExpensesToJson(List<RandomExpenses> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class RandomExpenses {
  String name;
  int amount;

  RandomExpenses({
    this.name,
    this.amount,
  });

  factory RandomExpenses.fromJson(Map<String, dynamic> json) => RandomExpenses(
        name: json["name"],
        amount: json["amount"],
      );

  Map<String, dynamic> toJson() => {
        "name": name,
        "amount": amount,
      };
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  List<RandomExpenses> randomExpensesList = [
    RandomExpenses(name: "Rent", amount: 250),
    RandomExpenses(name: "Insurance", amount: 105)
  ];

  void saveData(String key, List<RandomExpenses> value) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString(key, randomExpensesToJson(value));
  }

  Future<List<RandomExpenses>> getData(String key) async {
    final prefs = await SharedPreferences.getInstance();
    String keyString = prefs.getString(key);
    return Future.value(randomExpensesFromJson(keyString));
  }

  void _incrementCounter() async {
    await saveData("key", randomExpensesList);
    List<RandomExpenses> list = await getData("key");

    print('${list[0].name} ${list[0].amount}');
    print('${list[1].name} ${list[1].amount}');

    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

关于json - 在 Flutter 中将 Json 数组转换为 List<Object>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61581228/

相关文章:

android - 我可以使用agora_rtc在Flutter中实现一对一语音通话(VOIP)吗?

mysql - 通过 Node 将 JSON-Object 传递到 MYSQL 列

javascript - 如何仅将多维数组的一部分展平一个级别?

android - 如何将一个 API 重放的 JSON 中的值放到另一个 API post 方法的主体中?

javascript - AngularJS 将递归 JSON 解析为对象数组

flutter - 对象属性可以用作函数参数吗?

android - Flutter & AndroidX 不兼容 如何手动设置依赖

linux - Flutter 作为 Linux(非 Android)上的 GUI

flutter - 在小部件上方找不到正确的提供商

listview - 如何将索引从 Listview.builder 传递到项目小部件?