Flutter 浮动操作按钮错误!尝试创建一排具有响应式触摸效果的按钮

Posted

技术标签:

【中文标题】Flutter 浮动操作按钮错误!尝试创建一排具有响应式触摸效果的按钮【英文标题】:Flutter Floating action button error! Trying to create a row of button with a responsive touch effect 【发布时间】:2020-09-21 08:17:47 【问题描述】:

我的代码:

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],
              ),
            ),
          ),
        ),
      ),
     ),
   );

现实:

预期:

    当我点击一个按钮时,只有那个变成橙色,其余的保持白色。 当我再次单击它时,它再次变成灰色,就像其他地方一样。

【问题讨论】:

解释更多,添加包含它们的小部件代码 【参考方案1】:

我相信您希望为按钮实现某种切换行为。尽管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],
            ),
          ),
        ),
      ),
    );
  


【讨论】:

先生,谢谢您,但是,有没有更简单的方法来解决这个问题,我没有完全按照某些部分进行操作。 取决于您无法遵循的部分。我很确定这已经是一种更简单的方法。也许您可以将ButtonBar 替换为Row 小部件并获得类似的外观。

以上是关于Flutter 浮动操作按钮错误!尝试创建一排具有响应式触摸效果的按钮的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:向图像添加浮动操作按钮

在 Flutter 中定位两个浮动操作按钮

按下 Flutter 的浮动操作按钮的简单对话框

Flutter:如何从浮动操作按钮调用小部件状态类的方法

尝试创建一种有效的方法来产生具有组合结果的交叉连接

Flutter:在浮动操作按钮中使用 appBar 小部件而不是 appBar?