如何在Flutter中改变多个按钮中的一个按钮的颜色?

How to change the color of one button among several buttons in Flutter?

我是 Dart 和 Flutter 框架的新手。目前,我有一个填充了 25 个按钮的 GridView。默认情况下,每个按钮都有橙色背景色。但是,我想为用户提供一个选项,让他们可以长按任何按钮并显示一个 PopUpMenu,让他们可以选择为按钮选择不同的颜色。这是我尝试过的两件事:

  1. 设置一个改变颜色的全局变量。但是,当我改变它的状态时,它会改变所有按钮的颜色(我只想改变所选按钮的颜色)。
  2. 通过按钮的实例化传递局部变量,并将该变量传递给 PopUpMenu。但是,这不会改变按钮的任何内容。

我该如何解决这个问题?我在下面包含了一些代码片段来帮助您。请注意,此代码指的是#2 是如何实现的。

25 个按钮实例化:

    // Random number generator
    var _randGen = new Random();

    //List of maze cards
    List<Widget> mazeCards = new List();

    // Generate cards until it has 25 cards within the list
    while(mazeCards.length != 25)
    {

      // Get the index
      var _currIndex = _randGen.nextInt(words.length);
      // Add the card to the list
      var _cardColor = Colors.orange;
      mazeCards.add(createCard(words[_currIndex], _cardColor));

    }

创建名片方法:

  Widget createCard(String someString, Color _cardColor)
  {
    return GestureDetector(
          onTapDown: _storePosition,
          child: Container(
            padding: EdgeInsets.all(8.0),
            child:
              _createButton(someString, _cardColor)
          ),
    );
  }

createButton 方法:

  Widget _createButton(String someString, Color _cardColor)
  {

    Widget newButton = MaterialButton(
                padding: EdgeInsets.all(50.0),
                color: _cardColor,
                onPressed: () => _printButtonText(someString),
                onLongPress: () {
                  cardOptionsMenu(_cardColor);
                },
                textTheme: ButtonTextTheme.primary,
                 //_someColor(),
                child: Text(someString)
    );

    return newButton; 
  }

cardOptionsMenu 方法:

void cardOptionsMenu(Color _cardColor)
  {

    final RenderBox overlay = Overlay.of(context).context.findRenderObject(); 
    showMenu(
      context: context,
      ...
    )
    .then<void>((CardOptionEnum cardOption) {
      if (cardOption == null) return;
      else{
        switch (cardOption)
          {
            case CardOptionEnum.makeBlackCard:
              setState(() {
                _cardColor = Colors.black;
              });
              break;
            case CardOptionEnum.makeBlueCard:
              setState(() {
                _cardColor = Colors.blue;
              });
              break;
            case CardOptionEnum.makeRedCard:
              setState(() {
                _cardColor = Colors.red;
              });
              break;
            case CardOptionEnum.makeYellowCard:
              setState(() {
                _cardColor = Colors.yellow;

              });
              break;
            case CardOptionEnum.changeWord:

              break;
          }
      }
    });
  }

List<int> items = [];
  List<Color> colors = [];

  @override
  void initState() {
    super.initState();
    items = List.generate(25, (ind) => ind).toList();
    colors = List.generate(25, (ind) => Colors.orange).toList();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        itemCount: items.length,
        gridDelegate:
            SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
        itemBuilder: (con, ind) {
          return InkWell(
              child: Card(child: Text('${items[ind]}',
                                     style:TextStyle(color:Colors.white),
                                     textAlign:TextAlign.center), color: colors[ind]),
              onTap: () {
                changeColor(ind);
              });
        });
  }

  void changeColor(index) {
    showDialog(
        context: context,
        builder: (con) {
          return AlertDialog(
            title: Text('Choose a color !'),
            content: Column(mainAxisSize: MainAxisSize.min, children: [
              ListTile(
                  title: Text('Blue'),
                  onTap: () {
                    Navigator.of(con).pop();
                    changeState(index, Colors.blue);
                  }),
              ListTile(
                  title: Text('Red'),
                  onTap: () {
                    Navigator.of(con).pop();
                    changeState(index, Colors.red);
                  }),
              ListTile(
                  title: Text('Green'),
                  onTap: () {
                    Navigator.of(con).pop();
                    changeState(index, Colors.green);
                  })
            ]),
          );
        });
  }

  void changeState(index, color) {
    setState(() {
      colors[index] = color;
    });
  }