0

I am trying to make two switches toggle between on and off when they are clicked. I created a StatelessWidget class for the design of the switches. However, when I use this, and call the class in my User interface class, the switches do not change state. How can I update my code to allow for there to be a change?

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

and the following code is how I am calling it:

NotificationItem(
                title: 'New messages',
                emailStatus: emailStatus,
                pushStatus: pushStatus,
              )
helloworld12345
  • 176
  • 1
  • 4
  • 22

2 Answers2

1

In order to change UI state you have to use StatefulWidget You can either convert NotificationItem into a StatefulWidget or extract each switch into its own StatefulWidget

Or I recommend you to have a look at MVVM pattern using Get libary or Stacked

Your code with Get would look like this:

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,
                  ),
                ],
              ),
            ),
          ],
        );
      },
    );
  }
}
Andrey Gritsay
  • 979
  • 1
  • 10
  • 18
1

Since you are changing state, it has to be a StatefulWidget. Like so:

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);
                },
              ),
            ],
          ),
        ),
      ],
    );
  }
}
HBS
  • 580
  • 3
  • 6