我相信您希望为按钮实现某种切换行为。尽管ToggleBar 小部件对此有好处,但它对子小部件的期望并不灵活。因此,ButtonBar 小部件将有助于处理有关单击按钮的某种内部状态。这是一个可能对您有所帮助的可行解决方案。相同的代码可用作 codepen here。
接近
- 将按钮代码提取到名为
TButton 的小部件中,参数如下
-
isClicked - 一个布尔标志,表示按钮是否被点击。
-
foodItem - 要显示在按钮上的文本。
-
onPressed - 按下按钮时调用的回调函数。
- 在父小部件
MyButtons 中包含bool 列表,指示每个按钮的点击状态。
-
MyButtons 接受foodItems 的列表。迭代此列表并生成TButton 小部件列表并将其作为子级传递给ButtonBar。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue, scaffoldBackgroundColor: darkBlue),
home: Scaffold(
body: MyButtons(foodItems: ['Pizza', 'Burger', 'Kebab']),
),
);
}
}
class MyButtons extends StatefulWidget {
MyButtons({Key key, this.foodItems}) : super(key: key);
final List<String> foodItems;
@override
_MyButtonsState createState() => _MyButtonsState();
}
class _MyButtonsState extends State<MyButtons> {
List<bool> isSelected;
@override
initState() {
super.initState();
// initialize the selected buttons
isSelected = List<bool>.generate(widget.foodItems.length, (index) => false);
}
@override
Widget build(BuildContext context) {
return Padding(
// just for aesthetics
padding: const EdgeInsets.only(top: 80.0),
child: ButtonBar(
// use the alignment to positon the buttons in the screen horizontally
alignment: MainAxisAlignment.center,
// iterate over the foodItems and generate the buttons.
children: widget.foodItems.asMap().entries.map((entry) {
return TButton(
isClicked: isSelected[entry.key],
foodItem: entry.value,
onPressed: () {
setState(() {
isSelected[entry.key] = !isSelected[entry.key];
});
});
}).toList(),
),
);
}
}
class TButton extends StatelessWidget {
final bool isClicked;
final String foodItem;
/// OnPressed is passed from the parent. This can be changed to handle it using any state management.
final Function onPressed;
TButton(
{@required this.isClicked,
@required this.foodItem,
@required this.onPressed});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: isClicked ? Colors.orange[300] : Colors.white,
borderRadius: BorderRadius.circular(30.0),
),
child: FlatButton(
splashColor: Colors.orange[300],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
),
onPressed: onPressed,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 20.0,
),
child: Text(
foodItem,
style: TextStyle(
fontSize: 20.0,
color: isClicked ? Colors.white : Colors.grey[700],
),
),
),
),
);
}
}