Home > Blockchain >  Switch/Checkbox not updating on setState()
Switch/Checkbox not updating on setState()

Time:09-17

I've been doing this for 4 days, reading half of the Google and watching 3/4 of Youtube. I have a list of objects, I'm getting data from API. When those objects get generated into cards, Switch of Checkbox are not functiona, setState does not affect them at all. This is the original code, before I started trying things and messing up the code (thank you for Git).

Anyone got any ideas?

import 'dart:convert';
import 'dart:developer';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mojmegatel/API/get_settings_api.dart';
import 'package:mojmegatel/api/set_settings_api.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';

import '../constants.dart';
import 'dart:io';

class SettingsArray extends StatefulWidget {
  final ValueChanged onChanged;
  final bool isSwitched;

  const SettingsArray({
    required this.onChanged,
    required this.isSwitched,
    Key? key,
  }) : super(key: key);

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

class _SwitchWidget extends State<SettingsArray> {
  Future? dataFuture;
  bool isSwitched = false;

  @override
  void initState() {
    isSwitched = false;
    dataFuture = _getData();

    super.initState();
  }

  _getData() async {
    await GetSettings();

    SharedPreferences sharedPrefs = await SharedPreferences.getInstance();

    String sharedPrefsSettings = sharedPrefs.getString('settings').toString();
    String jsonSettings = await DefaultAssetBundle.of(context).loadString("assets/json/settings_data.json");

    String mergedData = await MergeData(jsonSettings, sharedPrefsSettings);
    return mergedData;
  }

  Future<String> MergeData(String jsonSettings, String sharedPrefsSettings) async {
    var decodedJsonSettings = json.decode(jsonSettings);
    var decodedSharedPrefsSettings = json.decode(sharedPrefsSettings);

    String mergedSettings = '[';

    bool found_id = false;
    bool is_last = false;

    String service_id;
    String name;
    String description;
    String servicerequestvalue;

    for (int i = 0; i < decodedJsonSettings.length; i  ) {
      for (int j = 0; j < decodedSharedPrefsSettings.length; j  ) {
        if (decodedJsonSettings[i]['service_id'] == decodedSharedPrefsSettings[j]['service_id']) {
          found_id = true;

          service_id = decodedJsonSettings[i]['service_id'];
          name = decodedJsonSettings[i]['title'];
          description = decodedJsonSettings[i]['description'];
          servicerequestvalue = decodedSharedPrefsSettings[j]['servicerequestvalue'];

          mergedSettings  = '{"service_id": "$service_id",';
          mergedSettings  = '"name": "$name",';
          mergedSettings  = '"description": "$description",';
          mergedSettings  = '"servicerequestvalue": "$servicerequestvalue"}';

          if (i == decodedJsonSettings.length - 1 && j == decodedSharedPrefsSettings.length - 1) {
            // Nothing, don't complicate
          } else {
            mergedSettings  = ',';
          }
        }
      }

      if (found_id == false) {
        service_id = decodedJsonSettings[i]['service_id'];
        name = decodedJsonSettings[i]['title'];
        description = decodedJsonSettings[i]['description'];

        mergedSettings  = '{"service_id": "$service_id",';
        mergedSettings  = '"name": "$name",';
        mergedSettings  = '"description": "$description",';
        mergedSettings  = '"servicerequestvalue": "0"}';

        if (i == decodedJsonSettings.length - 1) {
          // Nothing, don't complicate
        } else {
          mergedSettings  = ',';
        }
      } else {
        found_id = false;
      }
    }

    mergedSettings  = ']';

    return mergedSettings;
  }

  Widget build(BuildContext context) {
    List<Widget> widgetList = <Widget>[];

    return ListView.builder(
      shrinkWrap: true,
      physics: ScrollPhysics(),
      itemCount: 1,
      itemBuilder: (context, index) {
        return FutureBuilder(
          future: dataFuture,
          builder: (context, snapshot) {
            if (snapshot.data != null) {
              String service_id;
              String name;
              String description;

              var settingsData = json.decode(snapshot.data.toString());

              List<dynamic> list = settingsData;
              widgetList = <Widget>[];

              for (int i = 0; i < list.length; i  ) {
                String serviceRequestValue = settingsData[i]['servicerequestvalue'].toString();
                bool serviceRequestValueBool = true;

                service_id = settingsData[i]['service_id'].toString();
                name = settingsData[i]['name'].toString();
                description = settingsData[i]['description'].toString();

                log(service_id);

                if (serviceRequestValue == "1" || serviceRequestValue == "1,1" || serviceRequestValue == "14") {
                  serviceRequestValueBool = true;
                } else {
                  serviceRequestValueBool = false;
                }

                widgetList.add(settingsContainer(service_id, service_id, name, description, serviceRequestValueBool));
              }

              return Column(children: widgetList.toList());
            }

            return Column(
              children: [
                Container(
                  width: 60.0,
                  height: 80.0,
                  padding: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0),
                  child: SpinKitFoldingCube(color: MojMegaTelTheme.megaTelBlue), // CircularProgressIndicator(),
                ),
              ],
            );
          },
        );
      },
    );
  }

  Widget settingsContainer(String key, String serviceId, String title, String description, bool isSwitched) {
    return Padding(
      key: ValueKey(key),
      padding: const EdgeInsets.only(left: 24, right: 24, top: 16, bottom: 18),
      child: Container(
        decoration: BoxDecoration(
          color: MojMegaTelTheme.white,
          borderRadius: BorderRadius.only(topLeft: Radius.circular(8.0), bottomLeft: Radius.circular(8.0), bottomRight: Radius.circular(8.0), topRight: Radius.circular(8.0)),
          boxShadow: <BoxShadow>[
            BoxShadow(color: MojMegaTelTheme.grey.withOpacity(0.2), offset: Offset(1.1, 1.1), blurRadius: 10.0),
          ],
        ),
        child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(top: 16, left: 16, right: 24),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: <Widget>[
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          Padding(
                            padding: const EdgeInsets.only(left: 4, bottom: 3),
                            child: Row(
                              children: [
                                Text(
                                  title,
                                  overflow: TextOverflow.fade,
                                  maxLines: 1,
                                  softWrap: false,
                                  textAlign: TextAlign.center,
                                  style: TextStyle(
                                    fontFamily: MojMegaTelTheme.fontName,
                                    fontWeight: FontWeight.w600,
                                    fontSize: 14,
                                    color: MojMegaTelTheme.darkerText,
                                  ),
                                ),
                              ],
                            ),
                          ),
                          Padding(
                            padding: const EdgeInsets.only(left: 8),
                            child: Row(
                              children: [
                                Checkbox(
                                  value: isSwitched,
                                  onChanged: (value) {
                                    setState(
                                      () {
                                        isSwitched = value!;
                                        log("Swich: "   isSwitched.toString());
                                      },
                                    );
                                  },
                                ),
                              ],
                            ),
                          ),
                        ],
                      ),
                    ],
                  )
                ],
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 24, right: 24, top: 8, bottom: 8),
              child: Container(
                height: 2,
                decoration: BoxDecoration(
                  color: MojMegaTelTheme.background,
                  borderRadius: BorderRadius.all(Radius.circular(4.0)),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 24, right: 24, top: 8, bottom: 16),
              child: Row(
                children: <Widget>[
                  Expanded(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        Padding(
                          padding: const EdgeInsets.only(top: 6),
                          child: Text(
                            description,
                            textAlign: TextAlign.left,
                            style: TextStyle(
                              fontFamily: MojMegaTelTheme.fontName,
                              fontWeight: FontWeight.w600,
                              fontSize: 12,
                              color: MojMegaTelTheme.grey.withOpacity(0.5),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

CodePudding user response:

The problem come from here:

if (serviceRequestValue == "1" || serviceRequestValue == "1,1" || serviceRequestValue == "14") {
  serviceRequestValueBool = true;
} else {
  serviceRequestValueBool = false;
}

Your checkbox state already changes but it will rebuild your whole stateful widget, so the above code will take it back to the last state. You can create a separate stateful widget for the Switch and let it rebuild itself to fix this issue.

CodePudding user response:

You should wrap your widget with StatefulBuilder widget.

StatefulBuilder(
    builder: (context, _setState) => // Your Widget );
  • Related