Flutter/Dart - 在 null 上调用了方法 'setStringList'

Flutter/Dart - The method 'setStringList' was called on null

我是编程新手。我尝试了一些简单的事情,但我有一个错误,我无法再进一步。所以这是我得到的 NoSuchMethodError:

在 null 上调用了方法 'setStringList'。 接收者:空 尝试调用:setStringList("title", Instance(length:1) of '_GrowableList')

我现在将向您展示我认为错误的代码:

import 'dart:collection';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

import 'package:pro_todo/models/task.dart';

class TodosModel extends ChangeNotifier {
  List<Task> _tasks = [];
  SharedPreferences sharedPreferences;

  saveSharedPreferences() async {
    sharedPreferences = await SharedPreferences.getInstance();
    loadData();
  }

  UnmodifiableListView<Task> get allTasks => UnmodifiableListView(_tasks);
  UnmodifiableListView<Task> get incompleteTasks =>
      UnmodifiableListView(_tasks.where((task) => !task.completed));
  UnmodifiableListView<Task> get completedTasks =>
      UnmodifiableListView(_tasks.where((task) => task.completed));

  void addTodo(Task task) {
    _tasks.add(task);
    saveData();
    notifyListeners();
  }

  void toggleTodo(Task task) {
    final taskIndex = _tasks.indexOf(task);
    _tasks[taskIndex].toggleCompleted();
    notifyListeners();
  }

  void deleteTodo(Task task) {
    _tasks.remove(task);
    notifyListeners();
  }

  void saveData() {
    List<String> spList =
        _tasks.map((task) => json.encode(task.toMap())).toList();
    sharedPreferences.setStringList('title', spList);
    print(spList);
  }

  void loadData() {
    List<String> spList = sharedPreferences.getStringList('task');
    _tasks = spList.map((task) => Task.fromMap(json.decode(task))).toList();
    notifyListeners();
  }
}

at void saveData => sharedPreferences.setStringList('title', spList) 错误。如果我将其标记为注释,程序不会给我任何错误,但它也不会保存数据。

我认为要了解 _tasks 列表,您需要查看以下代码:

import 'package:flutter/material.dart';

class Task {
  String title;
  bool completed;

  Task({@required this.title, this.completed = false});

  void toggleCompleted() {
    completed = !completed;
  }

  Task.fromMap(Map map)
      : this.title = map['title'],
        this.completed = map['completed'];

  Map toMap() {
    return {
      'title': this.title,
      'completed': this.completed,
    };
  }
}

这是调用 addTask 方法的方法:

void onAdd() {
    final String textVal = taskTitleController.text;
    final bool completed = completedStatus;
    if (textVal.isNotEmpty) {
      final Task task = Task(
        title: textVal,
        completed: completed,
      );
      Provider.of<TodosModel>(context, listen: false).addTodo(task);
      Navigator.pop(context);
    }
  }

我希望任何人都可以帮助并提前谢谢你!

当您调用您的方法时,您的 SharedPreferences 实例未初始化 saveData 在设置列表之前,您必须用 sharedPreferences = await SharedPreferences.getInstance(); 初始化它。

  SharedPreferences sharedPreferences;

  SharedPreferences  _getSharedPreferences() async {
    if(sharedPreferences == null){
        sharedPreferences = await SharedPreferences.getInstance();
    }
    return sharedPreferences;
  }

  void saveData() async {
    List<String> spList =
        _tasks.map((task) => json.encode(task.toMap())).toList();
    _getSharedPreferences().setStringList('title', spList);
    print(spList);
  }

  void loadData() {
    List<String> spList = _getSharedPreferences().getStringList('task');
    _tasks = spList.map((task) => Task.fromMap(json.decode(task))).toList();
    notifyListeners();
  }