3
required this.favorite,

I got the bool value from the previous page like this. Since I used the pageview, I want to store the value in the index like this and use it later.

  loadFavorite() async{
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      favorite= prefs.getBoolList(_favoriteButton[index])!;
    });
  }


  void delete() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setBool(_favoriteButton[index], false);
    setState(() {
      favorite= prefs.getBool(_favoriteButton[index])!;
    });
  }

  void saved() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setBool(_favoriteButton[index], true);
    setState(() {
      favorite= prefs.getBool(_favoriteButton[index])!;
    });
  }

And I use the above code like this in the previous page. This is why I need a list. Without it I would have to create hundreds of pages.

  void loadFavorite() async{
    print(FavoriteButtons[0]);
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      favorite[0] = prefs.getBool(_favoriteButton[0])!;

Is it possible to create a list from shared_preferences? And how can I store bool as a list?

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
eno2
  • 73
  • 11

5 Answers5

4

You can hold bool list by this method:

List<bool> favorite = <bool>[];

Future<void> loadFavorite() async{
  SharedPreferences prefs = await SharedPreferences.getInstance();
  setState(() {
    favorite = (prefs.getStringList("userFavorite") ?? <bool>[]).map((value) => value == 'true').toList();
  });
}

Future<void> delete() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  setState(() {
    favorite[index] = false;
  });
  await prefs.setStringList("userFavorite", favorite.map((value) => value.toString()).toList());
  setState(() {
    favorite = (prefs.getStringList("userFavorite") ?? <bool>[]).map((value) => value == 'true').toList();
  });
}

Future<void> saved() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  setState(() {
    favorite[index] = true;
  });
  await prefs.setStringList("userFavorite", favorite.map((value) => value.toString()).toList());
  setState(() {
    favorite = (prefs.getStringList("userFavorite") ?? <bool>[]).map((value) => value == 'true').toList();
  });
}
Røhäñ Dås
  • 528
  • 4
  • 13
2

You can try using SharedPreferences.setStringList by saving only the true favorite button index to the list. Something like this (see comment for detail):

void save(int index, bool isFavorite) async {
   SharedPreferences prefs = await SharedPreferences.getInstance();
   var favorites = prefs.getStringList('favorites')??[];

   // index as string item
   var strIndex = index.toString();

   if(isFavorite) {
     // Save index to list only if it it not exist yet.
     if(!favorites.contains(strIndex)) {
        favorites.add(strIndex);
     }
   } else {
      // Remove only if strIndex exist in list.
      if(favorites.contains(strIndex)) {
        favorites.remove(strIndex); 
      }
   }

   // Save favorites back
   prefs.setStringList('favorites', favorites);
}

Future<bool> isFavorite(int index) async {
   SharedPreferences prefs = await SharedPreferences.getInstance();
   var favorites = prefs.getStringList('favorites')??[];

   // index as string item
   var strIndex = index.toString();

   // If index is exist, then it is must be true.
   if(favorites.contains(strIndex) {
      return true;
   }
   
   return false;  
}


 // All item index in list is always true
 Future<List<int>> getFavoriteIndexes() async {
   SharedPreferences prefs = await SharedPreferences.getInstance();
   var favorites = prefs.getStringList('favorites')??[];

   var indexes = <int>[];
   for(var favIndex in favorites) {
       // return -1 if invalid fav index found
       int index = int.tryParse(favIndex) ?? -1;
       if(val != -1) {
          indexes.add(index);
       }
   }

    return indexes;
 }

Please be aware, that the code haven't been tested yet.

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
  • Is the above code saved in this way 'favorite[index]'? The code is too long and I haven't figured it out yet. – eno2 Nov 07 '21 at 14:29
0

You can only store a List<String> in SharedPreferences, but you can easily convert the list to and from boolean when reading/writing.

// List<bool> --> List<String>
boolValues.map((value) => value.toString()).toList();

// List<String> --> List<bool>
stringValues.map((value) => value == 'true').toList();
Lee3
  • 2,882
  • 1
  • 11
  • 19
0

Instead of saving it as a list save it individually with index like prefs.setBool('favoritrButton$index', isFavorite) where index will be dynamic. So when you retrieve a saved bool you can use prefs.getBool('favoriteButton$index');

Then you can use save method like

      void save(int index, bool isFavorite) async {
         SharedPreferences prefs = await SharedPreferences.getInstance();
          prefs.setBool('favoriteButton$index', isFavorite);
       }

and to get favourite

  Future<Bool> isFavorite(int index) async {
   SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getBool('favoritrButton$index')??true;
//?? true will return true if it's null
}
Kaushik Chandru
  • 15,510
  • 2
  • 12
  • 30
0

You can build an indexable bool list if you store your bool values under some generated keys like the the index.toString();

List boolist = List.empty(growable: true);

void loadList() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      prefs.getStringList('list')?.forEach((indexStr) {
        //this will add the booleans stored in prefs under the indexStr key
        boolist.add(prefs.getBool(indexStr));
        
      });
    });

You can work on the boollist now however you want, you just need to save the new prefs Stringlist and boolean values when you're done

void saveList() async {
        final prefs = await SharedPreferences.getInstance();
        List<String> transfer = List<String>.empty(growable: true);
        //this transfer list is needed so you can store your indexes as strings
        int index = 0;
        boollist.forEach((element) {
             //here you just populate the transfer list for every value in in your boolist and save the appropiate boolean values
             transfer.add(index.toString());
             prefs.setBool(index.toString(), element);
             index++
           });
        setState(() {
            // save the new index string list
            prefs.setStringList('list', transfer);
            
          });
        });
Csaba Mihaly
  • 149
  • 10