可见性不会在 flutter 中切换?
Visibility won't toggle in flutter?
我有一个 gridView,其中每个网格内部都有一个 FlatButton。该按钮应该触发我在 GridView 之外的另一个按钮的可见性。我已经在 onPressed 中设置了状态,以便在每次按下 GridView 按钮时更改 bool showCard。在我的 print 语句中,它说它正在工作,每次按下按钮时都会产生 true 和 false,但它不会改变另一个名为 'CheckoutCard()' 的按钮的可见性。谁能帮帮我?
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);
});
});
},
);
}
}
要在更改变量值时触发视图重建,您需要使用 setState
。
你在哪里改变 isVisible
变量的值,你需要用 setState
:
包围它
setState(() {
isVisible = !isVisible;
});
您正在 Button
中调用 setState
方法。我认为它不会改变 MyMenu
小部件的状态。我建议您将 Button
更改如下:
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,
);
}
}
之后,您需要在 MyMenu
小部件中声明两个变量,如下所示:
class _MyMenuState extends State<MyMenu> {
bool changeColor = false;
bool showCard = false;
@override
Widget build(BuildContext context) {
yourBuildMethod()
在您的 MyMenu
小部件中,您可以这样调用按钮:
MyButton(
tile: GridTile(child: SnubbImage),
color: changeColor
? Colors.blue[800]
: Colors.transparent,
onPressed: () {
setState(() {
changeColor = !changeColor;
showCard = !showCard;
});
},
),
然后像这样检查您的 Visibility
:
Visibility(
visible: showCard,
child: CheckoutCard(),
)
现在您的变量位于 MyMenu
小部件中,并且您正在调用 MyMenu
小部件中的 setState
函数。因此它将能够更新您的小部件的状态。希望对您有所帮助。
我有一个 gridView,其中每个网格内部都有一个 FlatButton。该按钮应该触发我在 GridView 之外的另一个按钮的可见性。我已经在 onPressed 中设置了状态,以便在每次按下 GridView 按钮时更改 bool showCard。在我的 print 语句中,它说它正在工作,每次按下按钮时都会产生 true 和 false,但它不会改变另一个名为 'CheckoutCard()' 的按钮的可见性。谁能帮帮我?
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);
});
});
},
);
}
}
要在更改变量值时触发视图重建,您需要使用 setState
。
你在哪里改变 isVisible
变量的值,你需要用 setState
:
setState(() {
isVisible = !isVisible;
});
您正在 Button
中调用 setState
方法。我认为它不会改变 MyMenu
小部件的状态。我建议您将 Button
更改如下:
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,
);
}
}
之后,您需要在 MyMenu
小部件中声明两个变量,如下所示:
class _MyMenuState extends State<MyMenu> {
bool changeColor = false;
bool showCard = false;
@override
Widget build(BuildContext context) {
yourBuildMethod()
在您的 MyMenu
小部件中,您可以这样调用按钮:
MyButton(
tile: GridTile(child: SnubbImage),
color: changeColor
? Colors.blue[800]
: Colors.transparent,
onPressed: () {
setState(() {
changeColor = !changeColor;
showCard = !showCard;
});
},
),
然后像这样检查您的 Visibility
:
Visibility(
visible: showCard,
child: CheckoutCard(),
)
现在您的变量位于 MyMenu
小部件中,并且您正在调用 MyMenu
小部件中的 setState
函数。因此它将能够更新您的小部件的状态。希望对您有所帮助。