flutter - Flutter 浮动操作按钮错误!尝试创建一排具有响应式触摸效果的按钮
问题描述
我的代码:
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 使用。
方法
- 将您的按钮代码提取到一个
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],
),
),
),
),
);
}
}
推荐阅读
- python - 内核与 jupyter 和 matplotlib 一起下降
- python - PyQt5 - 启动线程不执行 run() 函数
- javascript - 使用 ES6 运行带有 JS 和依赖项的 Mocha
- expo - 世博会应用程序 aws-exports.js 在生产重定向 url 中?
- python - django 错误:NoReverseMatch 在 /watchlist/ Reverse for 'viewList' with arguments '('',)'
- python - 在循环中删除直方图的水平线
- sparql - 如何确定一个范围是否包含另一个?
- json - 将巨大的 Json 对象保存到 Oracle DB
- python - 如何取消pandas数据框
- python - python队列中的合并函数