Reputation: 329
I've got a gridView where each grid has a FlatButton inside it. The button is supposed to trigger the visibility for another button I have outside the GridView. I've set the state in onPressed to change the bool showCard for everytime the GridView button is pressed. In my print statement, it's saying that it's working, producing true and false each time the button is pressed, but it's not changing the visibility of the other button called 'CheckoutCard()'. Can anyone help me?
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:bee/Cards/Items%20Card.dart';
import 'package:bee/Constants/Constants.dart';
import 'package:bee/MerchantCategories/My Categories.dart';
import 'package:bee/MenuButtons/Color Changer.dart';
import 'package:bee/Cards/Checkout Card.dart';
import 'package:bee/main.dart';
import 'Basket Menu.dart';
class MyMenu extends StatefulWidget {
@override
_MyMenuState createState() => _MyMenuState();
}
class _MyMenuState extends State<MyMenu> {
// bool showCard = _MyButtonState().showCard;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
brightness: Brightness.light,
leading: new IconButton(
icon: new Icon(Icons.arrow_back, color: Colors.black),
onPressed: () { Navigator.of(context).pop();},
),
backgroundColor: Colors.white,
title: Padding(
padding: const EdgeInsets.all(6.0),
child: Image(image: AssetImage('images/Merchants/My_Image.png'),),
),
elevation: 1.0,
centerTitle: true,
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 15.0),
child: IconButton(icon: Icon(Icons.shopping_basket, color: Colors.blue[800],),
onPressed: (){ Navigator.push(context, MaterialPageRoute(builder: (context){return BasketMenu();})); }
),
),
],
),
body: Stack(
children: <Widget>[
Flex(
direction: Axis.vertical,
children: <Widget>[
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
child: ListView(children: <Widget>[
MyCategories(categoryText: Text('Restaurants', style: categoryTextStyle),),
MyCategories(categoryText: Text('Bars', style: categoryTextStyle),),
MyCategories(categoryText: Text('Games', style: categoryTextStyle),),
],
scrollDirection: Axis.horizontal,
),
),
),
),
Expanded(
flex: 10,
child: Container(
child: GridView.count(
crossAxisCount: 2,
children: <Widget>[
ItemsCard(
categoryName: Text('Fast Food', style: secondCategoryTextStyle,),
itemText: FastFoodText,
priceText: Text('£21.67', style: priceTextStyle,),
gridOutline: MyButton(
tile: GridTile(
child: FastFoodImage,
),
),
),
ItemsCard(
itemText: SnubbText,
priceText: Text('£44.95', style: priceTextStyle,),
gridOutline: MyButton(
tile: GridTile(
child: SnubbImage,
),
),
),
ItemsCard(
itemText: FreshText,
priceText: Text('£41.23', style: priceTextStyle,),
gridOutline: MyButton(
tile: GridTile(
child: FreshImage,
),
),
),
Container(),
],
),
),
),
],
),
Visibility(visible: _MyButtonState().showCard ? _MyButtonState().showCard : !_MyButtonState().showCard, child: CheckoutCard()),
],
),
);
}
}
class MyButton extends StatefulWidget {
@override
State<StatefulWidget> createState(){
return _MyButtonState();
}
MyButton({this.tile});
final GridTile tile;
bool isVisible = false;
int itemNumber = 0;
bool showCheckoutCard(){
return isVisible = !isVisible;
}
int itemCounter(){
return itemNumber++;
}
}
class _MyButtonState extends State<MyButton> {
bool changeColor = false;
static var myNewButtonClass = MyButton();
bool showCard = myNewButtonClass.isVisible;
@override
Widget build(BuildContext context) {
return FlatButton(
shape: Border(bottom: BorderSide(color: changeColor ? Colors.blue[800] : Colors.transparent, width: 3.0)),
child: widget.tile,
onPressed: (){
setState(() {
changeColor = !changeColor;
myNewButtonClass.itemCounter();
print(myNewButtonClass.itemCounter());
setState(() {
showCard = !showCard;
print(showCard);
});
});
},
);
}
}
Upvotes: 0
Views: 2500
Reputation: 2236
You are calling the setState
method inside your Button
. I don't think it will change the state of your MyMenu
widget. I would suggest you to change your Button
as following:
class MyButton extends StatelessWidget {
final Color color;
final GridTile tile;
final VoidCallback onPressed;
const MyButton({Key key, this.color, this.tile, this.onPressed})
: super(key: key);
@override
Widget build(BuildContext context) {
return FlatButton(
shape: Border(bottom: BorderSide(color: color)),
child: tile,
onPressed: onPressed,
);
}
}
After that, you need to declare two variable in your MyMenu
widget as follows:
class _MyMenuState extends State<MyMenu> {
bool changeColor = false;
bool showCard = false;
@override
Widget build(BuildContext context) {
yourBuildMethod()
In your MyMenu
widget you can call button like this:
MyButton(
tile: GridTile(child: SnubbImage),
color: changeColor
? Colors.blue[800]
: Colors.transparent,
onPressed: () {
setState(() {
changeColor = !changeColor;
showCard = !showCard;
});
},
),
And now check your Visibility
like this:
Visibility(
visible: showCard,
child: CheckoutCard(),
)
Now your variables are in your MyMenu
widget and you are calling setState
function in MyMenu
widget. So it will be able to update the state of your widget. I hope this will be helpful for you.
Upvotes: 1
Reputation: 9635
To trigger a rebuild of your view based when changing the value of a variable you need to use setState
.
Where you are are changing the value of the isVisible
variable, you need to surround it with a setState
:
setState(() {
isVisible = !isVisible;
});
Upvotes: 1