Home > front end >  ToggleButton Color is not changing on clicking in Flutter
ToggleButton Color is not changing on clicking in Flutter

Time:10-20

In Flutter, I have a simple dynamically generated Toggle buttons, but for some reason they are not changing color on being clicked. Button selection value is fine upon clicking as checked with print statements.

var responses = responseArray;
  List<bool> isSelected = [];
  List<Widget> ratingWidgets = [];

  for (int i = 0; i < responses.length; i  ) {
    isSelected.add(false);
    ratingWidgets.add(Text(responses[i].toString()));
  }
 
  return Center(
      child: Column(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      SizedBox(
        height: 15.0,
      ),
      ToggleButtons(
        borderRadius: const BorderRadius.all(Radius.circular(8)),
        borderColor: Colors.blue,
        selectedColor: Colors.green, // This is not happening
        color: Colors.red,
        isSelected: isSelected,
        children: ratingWidgets,
        direction: Axis.horizontal,
        onPressed: (int index) {
          setState(() {
            for (int i = 0; i < isSelected.length; i  ) {
              isSelected[i] = i == index;
            }
          });
          print(isSelected);
        },
      ),

I also tried to use a method to generate color and set color variable, but that too didn't work, Where am I going wrong ?

Update:

Minimum Code to generate same error :

    import 'package:flutter/material.dart';
    import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
    
    void main() => runApp(MaterialApp(home: MyApp()));
    
    class MyApp extends StatefulWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      bool spinnerRun = false;
      List<List<String>> responseArray = [];
    
      @override
      void initState() {
        responseArray.add(["Very good", "Good", "Poor", "Very Poor"]);
        responseArray.add(["Good", "Better", "Best"]);
        responseArray.add(["Yes", "No", "MayBe"]);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          body: ModalProgressHUD(
            inAsyncCall: spinnerRun,
            child: Column(
              children: [
                SizedBox(
                  height: 50.0,
                ),
                for (int i = 0; i < 3; i  ) getToggleButttonBars(responseArray[i])
              ],
            ),
          ),
        );
      }
    
      getToggleButttonBars(List<String> responseArray) {
        var responses = responseArray;
        List<bool> isSelected = [];
        List<Widget> ratingWidgets = [];
    
        for (int i = 0; i < responses.length; i  ) {
          isSelected.add(false);
          ratingWidgets.add(Text(responses[i].toString()));
        }
    
        return Padding(
            padding: const EdgeInsets.all(8.0),
            child: ToggleButtons(
              borderRadius: const BorderRadius.all(Radius.circular(8)),
              selectedBorderColor: Colors.green,
              borderColor: Colors.blue,
              selectedColor: Colors.green, // This is not happening
              color: Colors.red,
              isSelected: isSelected,
              children: ratingWidgets,
              direction: Axis.horizontal,
              onPressed: (int index) {
                setState(() {
                  for (int i = 0; i < isSelected.length; i  ) {
                    isSelected[i] = i == index;
                  }
                });
                print(isSelected);
              },
            ));
      }
    }

CodePudding user response:

The main issue is here putting selected holder inside the build method, it will reset to the default value on every build. I think it would be better to use map or model class instead, I am using List<List<bool>> on state level for now.

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool spinnerRun = false;
  List<List<String>> responseArray = [];
  List<List<bool>> isSelected = [];

  @override
  void initState() {
    super.initState();
    responseArray.add(["Very good", "Good", "Poor", "Very Poor"]);
    responseArray.add(["Good", "Better", "Best"]);
    responseArray.add(["Yes", "No", "MayBe"]);

    for (int i = 0; i < responseArray.length; i  ) {
      isSelected.add(List.generate(responseArray[i].length, (index) => false));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: ModalProgressHUD(
        inAsyncCall: spinnerRun,
        child: Column(
          children: [
            SizedBox(
              height: 50.0,
            ),
            for (int i = 0; i < 3; i  ) getToggleButttonBars(i)
          ],
        ),
      ),
    );
  }

  getToggleButttonBars(int index) {
    var responses = responseArray[index];

    List<Widget> ratingWidgets = [];

    for (int i = 0; i < responses.length; i  ) {
      ratingWidgets.add(Text(responses[i].toString()));
    }

    return Padding(
        padding: const EdgeInsets.all(8.0),
        child: ToggleButtons(
          borderRadius: const BorderRadius.all(Radius.circular(8)),
          selectedBorderColor: Colors.green,
          borderColor: Colors.blue,
          selectedColor: Colors.green,
          color: Colors.red,
          isSelected: isSelected[index],
          children: ratingWidgets,
          direction: Axis.horizontal,
          onPressed: (int j) {
            for (int i = 0; i < isSelected.length; i  ) {
              isSelected[index][i] = j == i;
            }

            setState(() {});
          },
        ));
  }
}

  • Related