颤动中按钮状态之间的切换

时间:2019-08-01 13:43:40

标签: flutter dart

我正在制作带有三个自定义按钮的简单flutter应用程序,当我单击一个按钮时,它将更改此按钮的背景颜色。我想要实现的是当我在其他按钮被激活时单击按钮时,我想停用按钮并激活我刚刚单击的按钮。 自定义按钮由CircleButton类表示,即时消息在HomePageClass的主版本中使用其中三个。

我想知道应该关闭然后打开适当的按钮在哪里,在我看来,所有事情都应该在CircleButton类中处理。

圆形按钮类:

class CircleButton extends StatefulWidget {
  final VoidCallback onPressed;
  final String imageData;
  final String buttonName;
  CircleButton({this.onPressed, this.imageData, this.buttonName});
  @override
  _CircleButtonState createState() => _CircleButtonState();
}

class _CircleButtonState extends State<CircleButton> {
  bool _active = false;
  //bool isButtonActive = false;
  void handleTap() {
    setState(() {
      /*
      if(widget.buttonName == 'Mode'){
      }
      if(widget.buttonName =='Sounds'){
      }
      if(widget.buttonName =='Volume'){
      }
      isButtonActive = !isButtonActive;
      */
      _active = !_active;
      widget.onPressed();
    });
    //print('widget.isActive:' + isButtonActive.toString());
  }

  @override
  Widget build(BuildContext context) {
    double circleBoxSize = 50.0;
    return new Column(
      children: <Widget>[
        FlatButton(
          splashColor: Colors.transparent,
          highlightColor: Colors.transparent,
          onPressed: handleTap,
          child: new Container(
            width: circleBoxSize,
            height: circleBoxSize,
            decoration: new BoxDecoration(
                gradient: _active
                    ? LinearGradient(
                        begin: Alignment.bottomLeft,
                        end: Alignment.topRight,
                        colors: [
                            Color.fromRGBO(79, 172, 254, 1),
                            Color.fromRGBO(0, 242, 245, 1)
                          ])
                    : null,
                shape: BoxShape.circle,
                color: _active ? null : Color.fromRGBO(227, 230, 238, 1)),
            child: new Image.asset(
              this.widget.imageData,
              color: _active ? Color.fromRGBO(255, 255, 255, 1) : null,
              scale: 1.8,
            ),
          ),
        ),
        SizedBox(height: 14),
        new Text(
          this.widget.buttonName,
          style: TextStyle(
              fontFamily: "Roboto",
              fontSize: 14,
              color: Color.fromRGBO(140, 151, 173, 1),
              fontWeight: FontWeight.normal),
        )
      ],
    );
  }
}

我正在使用CircleButton对象的主页:

class _HomePageState extends State<HomePage> {
  bool _active = false;
  int iter = 0;
  String activeButton;
  List<String> selectBarData = ['dasdasdas'];
  List<String> modes = ['deep-sleep', 'pain-relief'];
  List<String> sounds = ['campfire', 'rain'];

  void handleButtonsPress(){
    setState(){

    }
  }


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          body: Column(
        children: <Widget>[
          Container(
              padding: EdgeInsets.only(left: 25, right: 25, top: 60),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <CircleButton>[
                  new CircleButton(
                    onPressed: handleButtonsPress,
                    imageData: 'assets/body-organ.png',
                    buttonName: 'Mode',
                  ),
                  new CircleButton(
                    onPressed: handleButtonsPress,
                    imageData: 'assets/audio.png',
                    buttonName: 'Sounds',
                  ),
                  new CircleButton(
                    onPressed: handleButtonsPress,
                    imageData: 'assets/speaker.png',
                    buttonName: 'Volume',
                  )
                ],
              )),
          selectBar()
        ],
      )),
    );
  }
}

当我启动应用程序并单击第一个按钮时,它看起来像这样:

enter image description here

当我单击第二个按钮时,它看起来像这样:

enter image description here

但是我想要这样的结果:

enter image description here

1 个答案:

答案 0 :(得分:1)

我没有机会进行测试,但是应该可以。我创建了一个ValueChange回调,该回调将按钮的已分配标签返回给父级。这使您可以根据_active是否等效于按钮的标签来更改按钮的状态(有效)。希望这是有道理的。这是代码,在我更改的某些部分中有注释。如果您有任何疑问或问题,请告诉我!

首页:

class _HomePageState extends State<HomePage> {
  String _active;
  int iter = 0;
  String activeButton;
  List<String> selectBarData = ['dasdasdas'];
  List<String> modes = ['deep-sleep', 'pain-relief'];
  List<String> sounds = ['campfire', 'rain'];

  // ValueChanged<String> callback
  void active(String btn) {
    setState(() => _active = btn);
  }


  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          body: Column(
        children: <Widget>[
          Container(
              padding: EdgeInsets.only(left: 25, right: 25, top: 60),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <CircleButton>[
                  new CircleButton(
                    action: active, //pass data from child to parent
                    tag: "button1", //specifies attribute of button
                    active: _active == "button1" ? true : false, //set button active based on value in this parent
                    imageData: 'assets/body-organ.png',
                    buttonName: 'Mode',
                  ),
                  new CircleButton(
                    action: active,
                    tag: "button2",
                    active: _active == "button2" ? true : false,
                    imageData: 'assets/audio.png',
                    buttonName: 'Sounds',
                  ),
                  new CircleButton(
                    action: active,
                    tag: "button3",
                    active: _active == "button2" ? true : false,
                    imageData: 'assets/speaker.png',
                    buttonName: 'Volume',
                  )
                ],
              )),
          selectBar()
        ],
      )),
    );
  }
}

按钮:

class CircleButton extends StatefulWidget {
  final ValueChanged<String> action; //callback value change
  final String tag; //tag of button
  final String imageData;
  final String buttonName;
  final bool active; // state of button
  CircleButton({this.action, this.imageData, this.buttonName, this.active, this.tag});
  @override
  _CircleButtonState createState() => _CircleButtonState();
}

class _CircleButtonState extends State<CircleButton> {
  void handleTap() {
    setState(() {
      widget.action(widget.tag);
    });
  }

  @override
  Widget build(BuildContext context) {
    double circleBoxSize = 50.0;
    return new Column(
      children: <Widget>[
        FlatButton(
          splashColor: Colors.transparent,
          highlightColor: Colors.transparent,
          onPressed: handleTap,
          child: new Container(
            width: circleBoxSize,
            height: circleBoxSize,
            decoration: new BoxDecoration(
                gradient: widget.active
                    ? LinearGradient(
                        begin: Alignment.bottomLeft,
                        end: Alignment.topRight,
                        colors: [
                            Color.fromRGBO(79, 172, 254, 1),
                            Color.fromRGBO(0, 242, 245, 1)
                          ])
                    : null,
                shape: BoxShape.circle,
                color: widget.active ? null : Color.fromRGBO(227, 230, 238, 1)),
            child: new Image.asset(
              this.widget.imageData,
              color: widget.active ? Color.fromRGBO(255, 255, 255, 1) : null,
              scale: 1.8,
            ),
          ),
        ),
        SizedBox(height: 14),
        new Text(
          this.widget.buttonName,
          style: TextStyle(
              fontFamily: "Roboto",
              fontSize: 14,
              color: Color.fromRGBO(140, 151, 173, 1),
              fontWeight: FontWeight.normal),
        )
      ],
    );
  }
}

希望这会有所帮助!