Конвертировать Json массив в список <Object>в флаттер - PullRequest
0 голосов
/ 03 мая 2020

Я новичок в 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>'

Теперь, допустим, что я каким-то образом успешно храню его в общих настройках, как мне преобразовать JSON массив обратно в список при вызове с prefs.getString('key')?

Если вам нужно увидеть класс, вот он:

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};
}

1 Ответ

0 голосов
/ 04 мая 2020

Вы можете скопировать и вставить полный код ниже
Вы можете сохранить List<RandomExpenses> как json строку с randomExpensesToJson(value)
Вы можете получить 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),
      ),
    );
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...