如何在Flutter中改变多个按钮中的一个按钮的颜色?
How to change the color of one button among several buttons in Flutter?
我是 Dart 和 Flutter 框架的新手。目前,我有一个填充了 25 个按钮的 GridView。默认情况下,每个按钮都有橙色背景色。但是,我想为用户提供一个选项,让他们可以长按任何按钮并显示一个 PopUpMenu,让他们可以选择为按钮选择不同的颜色。这是我尝试过的两件事:
- 设置一个改变颜色的全局变量。但是,当我改变它的状态时,它会改变所有按钮的颜色(我只想改变所选按钮的颜色)。
- 通过按钮的实例化传递局部变量,并将该变量传递给 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;
});
}
我是 Dart 和 Flutter 框架的新手。目前,我有一个填充了 25 个按钮的 GridView。默认情况下,每个按钮都有橙色背景色。但是,我想为用户提供一个选项,让他们可以长按任何按钮并显示一个 PopUpMenu,让他们可以选择为按钮选择不同的颜色。这是我尝试过的两件事:
- 设置一个改变颜色的全局变量。但是,当我改变它的状态时,它会改变所有按钮的颜色(我只想改变所选按钮的颜色)。
- 通过按钮的实例化传递局部变量,并将该变量传递给 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;
});
}