可见性不会在 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 函数。因此它将能够更新您的小部件的状态。希望对您有所帮助。