skip to Main Content

Currently I want to use the SwitchListTile Widget divided into 1 separate Widget to reuse many times, but when I click on it, nothing happens.

Here is my code:

class SwitchScreen extends StatefulWidget {
  const SwitchScreen({super.key});

  @override
  State<SwitchScreen> createState() => _SwitchScreenState();
}

class _SwitchScreenState extends State<SwitchScreen> {
  bool check = false;

  Widget _buildSwitchListTile(String title, String description, bool currentValue) {
    return SwitchListTile(
      title: Text(title),
      value: currentValue,
      subtitle: Text(description),
      onChanged:(newValue) {setState(() { currentValue = newValue; });},
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Filters'),
      ),
      body: Column(
        children: [
          Container(
            padding: const EdgeInsets.all(20),
            child: Text(
              'select',
            ),
          ),
          Expanded(
            child: ListView(
              children: [
                _buildSwitchListTile(
                  'text',
                  'description',
                  check,
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}

I tried to fix it and it was successful, by passing a function to my custom Widget like the code below:

class SwitchScreen extends StatefulWidget {
  const SwitchScreen({super.key});

  @override
  State<SwitchScreen> createState() => _SwitchScreenState();
}

class _SwitchScreenState extends State<SwitchScreen> {
  bool check = false;

  Widget _buildSwitchListTile(String title, String description, bool currentValue, Function(bool) updateValue) {
    return SwitchListTile(
      title: Text(title),
      value: currentValue,
      subtitle: Text(description),
      onChanged: updateValue,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Filters'),
      ),
      body: Column(
        children: [
          Container(
            padding: const EdgeInsets.all(20),
            child: Text(
              'select',
            ),
          ),
          Expanded(
            child: ListView(
              children: [
                _buildSwitchListTile(
                  'text',
                  'description',
                  check,
                  (newValue) {
                    setState(() {
                      check = newValue;
                    });
                  },
                 ),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}

it worked as I wanted, but I don’t really know why it did. Can anyone explain it to me please!

2

Answers


  1. Updated Code:

    Use this code to use multiple SwitchListTile

    class Options {
      final String title;
      final String description;
      bool currentValue;
      Options(
          {required this.title,
          required this.description,
          required this.currentValue});
    }
    
    class SwitchScreen extends StatefulWidget {
      const SwitchScreen({super.key});
    
      @override
      State<SwitchScreen> createState() => _SwitchScreenState();
    }
    
    class _SwitchScreenState extends State<SwitchScreen> {
      List<Options> optionsList = [
        Options(
          title: 'text',
          description: 'description',
          currentValue: false,
        ),
      ];
    
      _buildSwitchListTile(
          {required String title,
          required bool currentValue,
          required String description,
          required onChanged}) {
        return SwitchListTile(
          title: Text(title),
          value: currentValue,
          subtitle: Text(description),
          onChanged: onChanged,
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Filters'),
          ),
          body: Column(
            children: [
              Container(
                padding: const EdgeInsets.all(20),
                child: const Text(
                  'select',
                ),
              ),
              Expanded(
                child: ListView.builder(
                  itemCount: optionsList.length,
                  itemBuilder: (BuildContext context, int index) {
                    return _buildSwitchListTile(
                      title: optionsList[index].title,
                      description: optionsList[index].description,
                      currentValue: optionsList[index].currentValue,
                      onChanged: (newValue) {
                        setState(
                          () {
                            optionsList[index].currentValue = newValue;
                          },
                        );
                      },
                    );
                  },
                ),
              )
            ],
          ),
        );
      }
    }
    
    Login or Signup to reply.
  2. You can use SwitchListTile in new Stateful class and pass 3 parameters. Can also add typedef callback if you want to know the state of currentValue in each SwitchListTile.

    typedef ReturnSingleValue<T> = void Function(T value);
    
    class SwitchClass extends StatefulWidget {
      final String title;
      final String description;
      final bool currentValue;
      final ReturnSingleValue<bool> onChanged;
      const SwitchClass(
          {super.key,
          required this.currentValue,
          required this.title,
          required this.description,
          required this.onChanged});
    
      @override
      State<SwitchClass> createState() => _SwitchClassState();
    }
    
    class _SwitchClassState extends State<SwitchClass> {
      bool currentValue = false;
    
      @override
      void initState() {
        currentValue = widget.currentValue;
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return SwitchListTile(
          title: Text(widget.title),
          value: currentValue,
          subtitle: Text(widget.description),
          onChanged: (newValue) {
            setState(() {
              currentValue = newValue;
            });
            widget.onChanged(newValue);
          },
        );
      }
    }
    

    And call the SwitchClass in parent Widget.

    ListView(
                  children: [
                    _buildSwitchListTile(
                      'text',
                      'description',
                      check,
                    ),
                    _buildSwitchListTile(
                      'text',
                      'descrisption',
                      check,
                    ),
                    SwitchClass(
                      title: 'text',
                      description: 'desc',
                      currentValue: check,
                      onChanged: (value) {
                        print('firstButton $value');
                      },
                    ),
                    SwitchClass(
                      title: 'text',
                      description: 'desc',
                      currentValue: check,
                      onChanged: (value) {
                        print('secondButton $value');
                      },
                    ),
                  ],
                ),
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search