Reputation: 618
I register the post id that the user likes to the list and check whether he likes it or not.
According to the result, I want to set icon and color with IconButton in SliverAppBar, but does not work.
The basic structure of my code is like here. I don't know how I could do it differently.
class Favorite {
List<String> fav = List<String>();
bool checkFav(String id) => fav.contains(id);
addItemToFav(String id) {
fav.add(id);
}
deleteItemToFav(String id) {
fav.remove(id);
}
}
class DetailPage extends StatefulWidget {
final Model blogModel;
DetailPage({this.blogModel});
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
Favorite favorite = new Favorite();
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return SafeArea(
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
flexibleSpace: FlexibleSpaceBar(),
leading: IconButton(),
actions: [
IconButton(
onPressed: () {
favorite.checkFav(widget.blogModel.id)
? favorite.deleteItemToFav(widget.blogModel.id)
: favorite.addItemToFav(widget.blogModel.id);
print(favorite.p());
setState(
() {
favorite.checkFav(widget.blogModel.id)
? color = Colors.red
: color = Colors.black;
},
);
},
icon: Icon(
favorite.checkFav(widget.blogModel.id)
? Icons.favorite
: Icons.favorite_border,
color: color),
),
],
),
];
},
body: Container(),
),
),
);
}
}
Upvotes: 0
Views: 1938
Reputation: 1866
Favorite favorite = new Favorite();
The reason why it's not working is because your favorite
instance is being re-created very frequently inside the widget's build() method.
When you call setState (or frequently when Flutter repaints and invokes the build() method), you're basically re-creating a new instance of Favorite.
Hence, why you lose the state of Favorites and why, when you print the list, it's empty.
So you could move the favorite object out like Salih Can showed you, that's one option.
Unfortunately, that's also not going to work the moment you add more pages or widgets to this app.
If you navigate away, you're going to lose the state of that widget (because the favorite instance was an instance member of the widget's state class, and now the widget has been garbage collected when navigating to a different widget).
This is known as ephemeral state, while you want app state (i.e. a state that persists no matter where you are in the app).
The simplest way to do this would be to use a State management solution like Provider. The linked flutter page shows a very simple way of how to set this up such that, no matter which widget you're inside of, you can be sure that your Favorites will be saved correctly.
Upvotes: 2
Reputation: 1783
You should move the following line of code above the 'build' method.
Favorite favorite = new Favorite();
It should look like this;
class _DetailPageState extends State<DetailPage> {
Favorite favorite = new Favorite();
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
....
Upvotes: 0
Reputation: 1880
List<String> fav = List<String>();
shouldn't be inside build()
method, but, inside state class.
Like
class _FavoriteWidgetState extends State<FavoriteWidget> {
List<String> fav = List<String>();
override
Widget build(BuildContext context) {
Upvotes: 1