选择另一个按钮时取消选择一个按钮

Deselect a button when another button is selected

我创建了一个自定义按钮,它根据 bool pressAttention 参数更改其图像和文本颜色。

class UserButton extends StatefulWidget {
  final String unselectedImagePath;
  final String selectedImagePath;
  final String text;

  UserButton({
    this.unselectedImagePath, 
    this.selectedImagePath, 
    this.text,
    });

  @override
  State<StatefulWidget> createState() => _UserButtonState();
}

class _UserButtonState extends State<UserButton> {
  bool pressAttention = false;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Ink.image(
          image: pressAttention
              ? AssetImage(widget.selectedImagePath)
              : AssetImage(widget.unselectedImagePath),
          fit: BoxFit.cover,
          width: 150.0,
          height: 150.0,
          child: InkWell(
            splashColor: Colors.transparent,
            highlightColor: Colors.transparent,
            onTap: () {
              setState(() {
                pressAttention = !pressAttention;
              });
            },
          ),
        ),
        Padding(
          padding: EdgeInsets.only(top: 30.0),
          child: Text(
            widget.text,
            style: TextStyle(
              color: pressAttention
                  ? Theme.of(context).accentColor
                  : Colors.white,
              fontFamily: "Roboto",
              fontSize: 18.0
            ),
          ),
        )
      ],
    );
  }
}

然后像这样在我的主 class 中给它们充气:

Padding(
            padding: EdgeInsets.only(top: 100.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                UserButton(
                  selectedImagePath: 'assets/whistle_orange.png',
                  unselectedImagePath: 'assets/whistle.png',
                  text: "Coach",
                ),
                Container(width: 30.0,),
                UserButton(
                  selectedImagePath: 'assets/weight_orange.png',
                  unselectedImagePath: 'assets/weight.png',
                  text: "Student",
                )
              ],
            ),
          ),

虽然这两个按钮本身可以正常工作,但我需要禁用第一个按钮(更改 pressAttention 并调用 setState()),反之亦然。

我怎样才能做到这一点?

您可以处理父窗口小部件的状态并将其传递给您的子窗口小部件,这是一个如何实现该目的的示例,当然您可以改进代码并创建您自己的 'parent' 控制器按钮:

    class UserButton extends StatefulWidget {
      final String unselectedImagePath;
      final String selectedImagePath;
      final String text;
      final VoidCallback onTap;
      final bool selected;

      UserButton({
        this.unselectedImagePath,
        this.selectedImagePath,
        this.text,
        this.selected,
        this.onTap,
      });

      @override
      State<StatefulWidget> createState() => _UserButtonState();
    }

    class _UserButtonState extends State<UserButton> {
      bool pressAttention = false;

      @override
      Widget build(BuildContext context) {
        pressAttention = widget.selected;
        return Column(
          children: <Widget>[
            Ink.image(
              image: pressAttention
                  ? AssetImage(widget.selectedImagePath)
                  : AssetImage(widget.unselectedImagePath),
              fit: BoxFit.cover,
              width: 150.0,
              height: 150.0,
              child: InkWell(
                splashColor: Colors.transparent,
                highlightColor: Colors.transparent,
                onTap: () {
                  setState(() {
                    pressAttention = !pressAttention;
                  });
                  if (widget.onTap != null) widget.onTap();
                },
              ),
            ),
            Padding(
              padding: EdgeInsets.only(top: 30.0),
              child: Text(
                widget.text,
                style: TextStyle(
                    color: pressAttention
                        ? Theme.of(context).accentColor
                        : Colors.white,
                    fontFamily: "Roboto",
                    fontSize: 18.0),
              ),
            )
          ],
        );
      }
    }

    class ParentMain extends StatefulWidget {
      @override
      _ParentMainState createState() => _ParentMainState();
    }

    class _ParentMainState extends State<ParentMain> {
      bool selectedButtonCoach = false;
      bool selectedButtonStudent = false;

      @override
      Widget build(BuildContext context) {
        return Container(
          child: Padding(
            padding: EdgeInsets.only(top: 100.0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                UserButton(
                  selectedImagePath: 'assets/whistle_orange.png',
                  unselectedImagePath: 'assets/whistle.png',
                  text: "Coach",
                  selected: selectedButtonCoach,
                  onTap: () {
                    setState(() {
                      selectedButtonCoach = true;
                      selectedButtonStudent = false;
                    });
                  },
                ),
                Container(
                  width: 30.0,
                ),
                UserButton(
                  selectedImagePath: 'assets/weight_orange.png',
                  unselectedImagePath: 'assets/weight.png',
                  text: "Student",
                  selected: selectedButtonStudent,
                  onTap: () {
                    setState(() {
                      selectedButtonCoach = false;
                      selectedButtonStudent = true;
                    });
                  },
                )
              ],
            ),
          ),
        );
      }
    }

看看收音机小部件的工作原理:https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/selection_controls_demo.dart

https://docs.flutter.io/flutter/material/Radio-class.html