How to toggle boolean value received from another widget
I would like to pass boolean initial boolean values as arguments to a stateful widget and then change its value besides updating the UI. As it stands, I only see the initial value and am not able to toggle the value. The code and the screenshots are as follows:
This is the widget from which I'm passing the arguments:
class OtherStuff extends StatefulWidget {
OtherStuffState createState() => OtherStuffState();
}
class OtherStuffState extends State<OtherStuff> {
@override
Widget build(BuildContext context) {
var provider = Provider.of<ModelClass>(context).data;
// TODO: implement build
return Container(
width: double.infinity,
height: 150,
color: Colors.transparent,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(left: 5),
child: const Text('Gets more interested with this', style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18
)),
),
SizedBox(height: 5),
Row(
children: [
StuffCards('https://static.toiimg.com/thumb/60892473.cms?imgsize=159129&width=800&height=800', false), //passing first value as false
SizedBox(width: 10),
StuffCards('https://thestayathomechef.com/wp-content/uploads/2016/06/Fried-Chicken-4-1.jpg', true), //passing second value as true
SizedBox(width: 10),
StuffCards('https://www.foodrepublic.com/wp-content/uploads/2012/03/033_FR11785.jpg', false), //passing third value as false
],
)
],
)
);
}
}
The stateful widget:
class StuffCards extends StatefulWidget {
final String imageUrl;
final bool clickedValue; //receiving the argument
StuffCards(this.imageUrl, this.clickedValue);
StuffCardsState createState() => StuffCardsState();
}
class StuffCardsState extends State<StuffCards> {
@override
Widget build(BuildContext context) {
var clicked = widget.clickedValue;
void clickedFav() {
setState(() {
clicked = !clicked; //toggling the value received
});
}
// TODO: implement build
return Stack(
children: [
// Container(
// width: 120,
// ),
Positioned(
child: Container(
width: 110,
height: 120,
margin: const EdgeInsets.only(left: 10),
decoration: BoxDecoration(
color: Theme.of(context).primaryColorDark,
borderRadius: const BorderRadius.only(
topRight: Radius.circular(100),
topLeft: Radius.circular(100),
bottomRight: Radius.circular(20),
bottomLeft: Radius.circular(20),
)
),
child: Padding(
padding: const EdgeInsets.only(top: 60),
child: Container(
width: double.infinity,
height: 60,
decoration: BoxDecoration(
color: Theme.of(context).primaryColorDark,
),
child: Column(
children: [
Text('Fried Squid', style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white
)),
Container(
width: 75,
color: Colors.transparent,
child: Text(
'₹ 245', style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 20
)),
),
Container(
width: double.infinity,
height: 16,
padding: EdgeInsets.only(right: 2, bottom: 1),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
InkWell(
onTap: clickedFav, //The inkwell doesn't seem to respond and update the UI
child: clicked ? Icon(
Icons.favorite,
color: Colors.red,
size: 15
) : Icon(
Icons.favorite_border,
color: Colors.white,
size: 15
)
)
],
),
)
],
),
),
),
),
),
Strangely enough, upon clicking the Inkwell widget, the value does get changed i.e If I click it and if the boolean value is false, it gets changed to true but doesn't change back to false. Also, as stated again, the UI doesn't update.
Solution 1:
Your UI doesn't change because
StuffCards('https://static.toiimg.com/thumb/60892473.cms?imgsize=159129&width=800&height=800', false),
Will never change. When you call setstate in the StuffCards class, the widget gets a rebuild, but with the same parameters.
So you have two options here
- you make a function in the OtherStuffState class that toggles the value, and you pass that function on to the StuffCards class, en you call that function when the ontap event occurs in the InkWell.
- you use provider to store the data and you make a function in the modelclass to toggle the card, so you just have to call in the StuffCards class
context.read<ModelClass>().toggleCard(cardNumber)