如何使用 shared_preferences 包来保存我的字符串列表?

时间:2021-08-01 21:17:33

标签: list flutter sharedpreferences

我正在尝试保存和读取名为“团队”的列表作为 shared_preference,因此每次我切换回此屏幕并查看我的团队列表时,它都不为空并显示旧值。无论我如何设置它似乎都不起作用。然后我回来列表是空的。大家有什么想法吗?

这是我的代码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class TeamScreen extends StatefulWidget {
  @override
  _TeamScreenState createState() => _TeamScreenState();
}

class _TeamScreenState extends State<TeamScreen> {
  List<String> teams = [];

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        itemCount: teams.length,
        itemBuilder: (context, index) {
          return Team(
            teams[index],
            () => removeTeam(teams[index]),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => newTeam(),
        child: Icon(
          CupertinoIcons.add,
        ),
      ),
    );
  }

  void addTeam(String name) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    setState(() {
      teams.add(name);
    });
    Navigator.of(context).pop();

    prefs.setStringList('teams', teams);
  }

  void newTeam() {
    showDialog<AlertDialog>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Name auswählen: '),
          content: TextField(
            onSubmitted: addTeam,
          ),
        );
      },
    );
  }

  void removeTeam(String name) {
    setState(() {
      teams.remove(name);
    });
  }
}

class Team extends StatelessWidget {
  final String name;
  final Function remove;
  const Team(this.name, this.remove);

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 22),
      child: ListTile(
        leading: Icon(Icons.sports_volleyball_outlined),
        contentPadding: EdgeInsets.symmetric(vertical: 8.0),
        title: Text(
          name,
          style: TextStyle(
            fontSize: 18.0,
            fontWeight: FontWeight.w600,
          ),
        ),
        trailing: IconButton(
          icon: Icon(CupertinoIcons.delete),
          onPressed: () => remove(),
        ),
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:0)

你的代码看起来几乎完美!只是您没有使用 SharedPreferences 中的 initState 初始化您的团队变量。 让我们解决这个问题:

  1. 定义一个偏好变量
class _TeamScreenState extends State<TeamScreen> {
  List<String> teams = [];
  late SharedPreferences prefs;    //Declare your prefs variable here but with late initializer.
...
  1. 检查团队列表是否存储在本地 -> 获取它,否则 -> 使用空列表创建它。
void initState() {
    super.initState();
    tryListFetch();  // defined async function
}

void tryListFetch() async {
    prefs = await SharedPreferences.getInstance();
    if (!prefs.containsKey('teams')) {
      prefs.setStringList('teams', []);   // created empty teams list on local storage
      print('On device data is not available.');
      return;
    }
    print('data avaialble');
    teams = prefs.getStringList('teams') as List<String>;
  }

  1. 每当您更改团队变量时更新您的本地数据:
prefs.setStringList('teams', teams);

就像在您的 removeTeam 函数中一样:

void removeTeam(String name) {
    setState(() {
      teams.remove(name);
    });
    prefs.setStringList('teams', teams);  //updated local storage's list
  }

在您的 addTeam 函数中:

void addTeam(String name) async {
    // SharedPreferences prefs = await SharedPreferences.getInstance();  //no need to initialize it here as we have already initialized it globally!

    setState(() {
      teams.add(name);
    });
    Navigator.of(context).pop();

    prefs.setStringList('teams', teams);
  }

完成!