Pramod Yadav
Pramod Yadav

Reputation: 454

Favourite Button in Flutter got unFavourited on Relaunch app

I have a ListView Item with Favourite icon and I want to add functionality so that I can add list into favourite list. data is successfully added to favourite list. Here is HomePage

body: ListView.builder(
        itemCount: 100,
        cacheExtent: 20.0,
        padding: const EdgeInsets.symmetric(vertical: 16),
        itemBuilder: (context, index) => ItemTile(index),
      ),

and My ListTile class I used

var favoritesList = Provider.of<Favorites>(context);

child: ListTile(
        leading: CircleAvatar(
          backgroundColor: Colors.primaries[index % Colors.primaries.length],
        ),
        title: Text(
          'Item $index',
          key: Key('text_$index'),
        ),
        trailing: IconButton(
          key: Key('icon_$index'),
          icon: favoritesList.items.contains(index)
              ? Icon(Icons.favorite, color: Colors.redAccent)
              : Icon(Icons.favorite_border),
          onPressed: () {
            !favoritesList.items.contains(index)
                ? favoritesList.add(index)
                : favoritesList.remove(index);
            Scaffold.of(context).showSnackBar(
              SnackBar(
                content: Text(favoritesList.items.contains(index)
                    ? 'Added to favorites.'
                    : 'Removed from favorites.'),
                duration: Duration(seconds: 1),
              ),
            );
          },
        ),
      ),

I have a model class favourites.dart

class Favorites extends ChangeNotifier {
  final List<int> _favoriteItems = [];
  List<int> get items => _favoriteItems;
  void add(int itemNo) {
    _favoriteItems.add(itemNo);
    notifyListeners();
  }
  void remove(int itemNo) {
    _favoriteItems.remove(itemNo);
    notifyListeners();
  }
}

and in my favouritePage. I am getting everything perfect and also can remove favourited item but when I reopen my app I did not get any favourited item.

here is my page FavouritePage.

body: Consumer<Favorites>(
        builder: (context, value, child) => ListView.builder(
          itemCount: value.items.length,
          padding: const EdgeInsets.symmetric(vertical: 16),
          itemBuilder: (context, index) => FavoriteItemTile(value.items[index]),
        ),
      ),

FavouriteItemTile

child: ListTile(
        leading: CircleAvatar(
          backgroundColor: Colors.primaries[itemNo % Colors.primaries.length],
        ),
        title: Text(
          'Item $itemNo',
          key: Key('favorites_text_$itemNo'),
        ),
        trailing: IconButton(
          key: Key('remove_icon_$itemNo'),
          icon: Icon(Icons.close),
          onPressed: () {
            Provider.of<Favorites>(context, listen: false).remove(itemNo);
            Scaffold.of(context).showSnackBar(
              SnackBar(
                content: Text('Removed from favorites.'),
                duration: Duration(seconds: 1),
              ),
            );
          },
        ),
      ),

please provide the solution and can I use shared preferences with provider.

Upvotes: 0

Views: 1727

Answers (3)

camelCase1492
camelCase1492

Reputation: 672

If you want to store on device us File(pathToFile).write(dataAsString) You might want to save the data as json using jsonEncode(listOfNumbers) and decode using jsonDecode()

Explanation: To save data, convert it to json and save to File on device

// NOTE: dataAsMap should be instance of class Map which stores the data you want to save
Directory localDirectory = await getApplicationDocumentsDirectory();
File(localDirectory.path + “/“ + “fileName.json”).writeAsStringSync(jsonEncode(dataAsMap));

To get data:

Map jsonData = jsonDecode(File(localDirectory.path + “/“ + “fileName.json”).readAsStringSync())

Upvotes: 0

Siddharth Agrawal
Siddharth Agrawal

Reputation: 3156

Yes. You should be using SharedPreferences. Add the preference library and these pieces of code Object.dart

class Object1{
  bool isLiked;
  String name;
  const Object1(this.name,this.isLiked);//Whatever fields you need
  factory User.fromJson(Map<String, dynamic> parsedJson) {
        return new Object1(
            name: parsedJson['name'] ?? "",
            isLiked: parsedJson['isLiked'] ?? "");
      }

      Map<String, dynamic> toJson() {
        return {
          "name": this.name,
          "isLiked": this.isLiked
        };
      }
}

Main.dart

void main(){

    setData();
    runApp(MyApp);

}
void setData() async{
 SharedPreferences prefs = await SharedPreferences.getInstance();
 List dataList = [Object1("Name",false).toJson()];//Your items in this format
 if prefs.getStringList("lists") == null:
    Map decode_options = jsonDecode(dataList);
    prefs.setStringList(jsonEncode(Object1.fromJson(decode_options)));
}

Now instead of a custom class for favourites, we will get all the data where we can filter. To retrieve the data afterwards, use this code

SharedPreferences prefs = await SharedPreferences.getInstance();
Map objectMap = jsonDecode(await shared_User.getStringList('list'));
List itemList = [];
for (item in objectMap):
   itemList.append(User.fromJson(item));

Now you can use this Item list with the properties and the isLiked feature which is a boolean to check whether it is showed or not.
This may seem complicated but is perfectly simple though your work would be much easier if you used a database like firebase and stored these as documents

Upvotes: 1

Alperen Ekin
Alperen Ekin

Reputation: 318

One option can be that you can store according to index value in shared preference and query that index value in order to see whether it is added as favourite or not. However it won't be efficient as the number of favourites increases, though still an option.

Upvotes: 0

Related Questions