Obscuritas
Obscuritas

Reputation: 59

How can I use the shared_preferences package to save my string list?

I'm trying to save and read a list called "teams" as a shared_preference so every time I switch back to this screen and take a look at my teams list it isn't empty and shows the old values. No matter how I set it up it doesn't seem to work. Then I come back the list is empty. Do you guys have any ideas?

Here is my code:

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(),
        ),
      ),
    );
  }
}

Upvotes: 0

Views: 94

Answers (1)

Aayush Shah
Aayush Shah

Reputation: 709

Your code seems almost perfect! just you didn't initialized your teams variable with the SharedPreferences in initState. lets fix that :

  1. Define a prefs variable
class _TeamScreenState extends State<TeamScreen> {
  List<String> teams = [];
  late SharedPreferences prefs;    //Declare your prefs variable here but with late initializer.
...
  1. Check if teams list is stored in local -> fetch it or if not -> create it with empty list.
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. Update your local data whenever you make changes in teams variable :
prefs.setStringList('teams', teams);

like in your removeTeam function :

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

And in your addTeam function :

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

Done !

Upvotes: 1

Related Questions