【问题标题】:How can I make the switches, which have their own StatelessWidget Class toggle when clicked?如何制作开关,它们在单击时具有自己的 StatelessWidget 类切换?
【发布时间】:2020-11-20 16:39:54
【问题描述】:

我试图让两个开关在单击时在打开和关闭之间切换。我为开关的设计创建了一个 StatelessWidget 类。但是,当我使用它并在我的用户界面类中调用该类时,开关不会改变状态。如何更新我的代码以允许进行更改?

import 'package:flutter/material.dart';

class NotificationItem extends StatelessWidget {
  NotificationItem(
      {@required this.title,
      @required this.pushStatus,
      @required this.emailStatus});

  String title;
  bool pushStatus;
  bool emailStatus;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        Expanded(
          child: Padding(
            padding: EdgeInsets.all(20),
            child: Text(
              title,
              style: TextStyle(
                  fontFamily: kFontFamilyNormal,
                  fontSize: 17,
                  color: AppColor.text,
                  fontWeight: FontWeight.w500),
            ),
          ),
        ),
        Expanded(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Switch(
                value: emailStatus,
                onChanged: (value) {
                  emailStatus = value;
                  print(emailStatus);
                },
                activeTrackColor: AppColor.primaryColorDark,
                activeColor: AppColor.white,
              ),
              Switch(
                value: pushStatus,
                onChanged: (value) {
                  pushStatus = value;
                  print(pushStatus);
                },
                activeTrackColor: AppColor.primaryColorDark,
                activeColor: AppColor.white,
              ),
            ],
          ),
        ),
      ],
    );
  }
}

下面的代码就是我的称呼:

NotificationItem(
                title: 'New messages',
                emailStatus: emailStatus,
                pushStatus: pushStatus,
              )

【问题讨论】:

标签: android-studio flutter dart uiswitch statefulwidget


【解决方案1】:

由于您要更改状态,因此它必须是 StatefulWidget。像这样:

class NotificationItem extends StatefulWidget {
  const NotificationItem({
    Key key,
    @required this.title,
    @required this.pushStatus,
    @required this.emailStatus,
  });
  final String title;
  final bool pushStatus;
  final bool emailStatus;

  @override
  _NotificationItemState createState() => _NotificationItemState();
}

class _NotificationItemState extends State<NotificationItem> {
  String _title;
  bool _pushStatus;
  bool _emailStatus;
  
  void initState() {
    super.initState();
    _title = widget.title;
    _pushStatus = widget.pushStatus;
    _emailStatus = widget.emailStatus;
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        Expanded(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Text(
              _title,
            ),
          ),
        ),
        Expanded(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Switch(
                value: _emailStatus,
                onChanged: (value) {
                  setState(() => _emailStatus = value);
                  print(_emailStatus);
                },
              ),
              Switch(
                value: _pushStatus,
                onChanged: (value) {
                  setState(() => _pushStatus = value);
                  print(_pushStatus);
                },
              ),
            ],
          ),
        ),
      ],
    );
  }
}

【讨论】:

    【解决方案2】:

    要更改 UI 状态,您必须使用 StatefulWidget 您可以将 NotificationItem 转换为 StatefulWidget 或将每个开关提取到其自己的 StatefulWidget 中

    或者我建议您使用 Get libaryStacked 看看 MVVM 模式

    您的 Get 代码如下所示:

    import 'package:flutter/material.dart';
    import 'package:get/get.dart';
    
    class NotificationItemViewModel extends GetxController {
      bool pushStatus = false;
      bool emailStatus = false;
    
      void changeEmailStatus(bool newValue) {
        emailStatus = newValue;
        print(emailStatus);
        update();
      }
    
      void changePushStatus(bool newValue) {
        pushStatus = newValue;
        print(pushStatus);
        update();
      }
    }
    
    class NotificationItem extends StatelessWidget {
      const NotificationItem({@required this.title});
    
      final String title;
    
      @override
      Widget build(BuildContext context) {
        return GetBuilder<NotificationItemViewModel>(
          init: NotificationItemViewModel(),
          builder: (model) {
            return Row(
              children: <Widget>[
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.all(20),
                    child: Text(
                      title,
                      style: TextStyle(
                        fontFamily: kFontFamilyNormal,
                        fontSize: 17,
                        color: AppColor.text,
                        fontWeight: FontWeight.w500,
                      ),
                    ),
                  ),
                ),
                Expanded(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Switch(
                        value: model.emailStatus,
                        onChanged: model.changeEmailStatus,
                        activeTrackColor: AppColor.primaryColorDark,
                        activeColor: AppColor.white,
                      ),
                      Switch(
                        value: model.pushStatus,
                        onChanged: model.changePushStatus,
                        activeTrackColor: AppColor.primaryColorDark,
                        activeColor: AppColor.white,
                      ),
                    ],
                  ),
                ),
              ],
            );
          },
        );
      }
    }
    

    【讨论】:

    • 您能否发布一个使用我的代码的示例?
    • 顺便推荐你使用lint包pub.dev/packages/lint
    • 您是否在pubspec.yaml 中添加了get: 依赖并启动了pub get