Flutter 浮动操作按钮错误!尝试创建一排具有响应式触摸效果的按钮
Flutter Floating action button error! Trying to create a row of button with a responsive touch effect
我的代码:
bool _isClicked = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 3.0),
child: 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: () {
setState(() {
_isClicked = !_isClicked;
});
},
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 20.0,
),
child: Text(
foodItem,
style: TextStyle(
fontSize: 20.0,
color: _isClicked ? Colors.white : Colors.grey[700],
),
),
),
),
),
),
);
现实:
期望值:
- 当我点击一个按钮时,只有那个变成橙色,其余的保持白色。
- 当我再次点击它时,它又像其他的一样变成灰色。
我相信您想为按钮实现某种切换行为。尽管 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],
),
),
),
),
);
}
}
我的代码:
bool _isClicked = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: EdgeInsets.symmetric(horizontal: 3.0),
child: 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: () {
setState(() {
_isClicked = !_isClicked;
});
},
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 20.0,
),
child: Text(
foodItem,
style: TextStyle(
fontSize: 20.0,
color: _isClicked ? Colors.white : Colors.grey[700],
),
),
),
),
),
),
);
现实:
期望值:
- 当我点击一个按钮时,只有那个变成橙色,其余的保持白色。
- 当我再次点击它时,它又像其他的一样变成灰色。
我相信您想为按钮实现某种切换行为。尽管 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],
),
),
),
),
);
}
}