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

现实:

期望值:

  1. 当我点击一个按钮时,只有那个变成橙色,其余的保持白色。
  2. 当我再次点击它时,它又像其他的一样变成灰色。

我相信您想为按钮实现某种切换行为。尽管 ToggleBar 小部件对此有好处,但它对子小部件的期望并不灵活。因此,ButtonBar 小部件将有助于了解有关单击按钮的某种内部状态。这是一个可能对您有帮助的可行解决方案。相同的代码可用作 codepen here.

接近

  1. 将您的按钮代码提取到名为 TButton 的小部件中,参数如下
    • isClicked - 一个布尔标志,表示是否单击了按钮。
    • foodItem - 要在按钮上显示的文本。
    • onPressed - 按下按钮时调用的回调函数。
  2. 在父小部件 MyButtons 中包含一个 bool 列表,指示每个按钮的点击状态。
  3. 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],
            ),
          ),
        ),
      ),
    );
  }
}