Flutter : How to use Riverpod with SharedPreference and List<String> Variable in multipage?
2,192
My recommended approach would be to create a StateNotifier that handles the state as well as the interactions with SharedPreferences. The following simplifies the logic in your widgets as well.
final sharedPrefs =
FutureProvider<SharedPreferences>((_) async => await SharedPreferences.getInstance());
class FavoriteIds extends StateNotifier<List<String>> {
FavoriteIds(this.pref) : super(pref?.getStringList("id") ?? []);
static final provider = StateNotifierProvider<FavoriteIds, List<String>>((ref) {
final pref = ref.watch(sharedPrefs).maybeWhen(
data: (value) => value,
orElse: () => null,
);
return FavoriteIds(pref);
});
final SharedPreferences? pref;
void toggle(String favoriteId) {
if (state.contains(favoriteId)) {
state = state.where((id) => id != favoriteId).toList();
} else {
state = [...state, favoriteId];
}
// Throw here since for some reason SharedPreferences could not be retrieved
pref!.setStringList("id", state);
}
}
Usage:
class DoaWidget extends ConsumerWidget {
const DoaWidget({Key? key, required this.doa}) : super(key: key);
final Doa doa;
@override
Widget build(BuildContext context, ScopedReader watch) {
final favoriteIds = watch(FavoriteIds.provider);
return IconButton(
icon: favoriteIds.contains('') ? Icon(Icons.favorite) : Icon(Icons.favorite_border),
color: favoriteIds.contains('') ? Colors.red : Colors.grey,
onPressed: () => context.read(FavoriteIds.provider.notifier).toggle(doa.id.toString()),
);
}
}
Author by
Bill Rei
Updated on December 29, 2022Comments
-
Bill Rei over 1 year
I've create
List<String> favId = [];
variable to store item's ID with SharedPreferences, so the favorited items ID didnt lost after I restart the application. And here is my SharedPreferences method and favorite IconButton in detailDoaPage.dart :... static List<String> favId = []; getData() async { SharedPreferences pref = await SharedPreferences.getInstance(); setState(() { favId = pref.getStringList("id") ?? []; }); } void initState() { super.initState(); getIds(); } getIds() async { favId = getData(); } void saveData() async { SharedPreferences pref = await SharedPreferences.getInstance(); pref.setStringList("id", favId); } ... IconButton( icon: Icon( favId.contains(doa.id.toString()) ? Icons.favorite : Icons.favorite_border, color: favId.contains(doa.id.toString()) ? Colors.red : Colors.grey, ), onPressed: () => setState(() { doa.fav = !doa.fav; if (favId.contains(doa.id.toString())) { favId.removeWhere( (element) => element == doa.id.toString()); } else { favId.add(doa.id.toString()); } saveData(); favId.sort(); }), )
Beside that, I also want to show the favorited item's with ListView.builder in favPage.dart (another page). Of course I want get the favId from detailDoaPage.dart. How can I implement the provider/riverpod across this 2 pages?
Here is the preview of my app :
Thank you :)
-
ambiguous58 about 3 yearsI can try to point you in the right direction. What you want to do is very similar to the todos example in the riverpod docs. You can treat your
bool isFavoriteDoa
similar to how they treatbool completed
. It's only two files of code take a look at them and try to implement the same solution in your app. -
Bill Rei about 3 years@ambiguous58 whoa, thank you so much for your advice. Yes I will learn for it :)
-
-
Bill Rei about 3 yearsI'm sorry, I'm still little confused. This is my code for this my two page (detailDoaPage.dart & favPage.dart) replit.com/join/nlzhbikh-nabilrei . Do you want to help me to revise my code with yours? Thank you :)
-
Alex Hartford about 3 yearsHappy to help, glad we could get your solution working! Thanks for introducing the replit tool to me as well.
-
LearnFlutter about 2 yearsHi, is there a possibility you could help on my issue where i would like to use riverpod. – stackoverflow.com/questions/70980002/…