skip to Main Content

I try to have a couple of checkboxes in a DropdownButton. When clicking the checkboxes I add the values to a list and use this list to keep state of which checkbox is active and which isn’t – but the checkboxes are not updated while the Dropdown is opened.

Here a small example – the values in checkedItems are correct but I always have to close and reopen the checkboxes to see the changes.

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  List availableItems = ["1", "2", "3", "4"];
  List checkedItems = [];


  @override
  Widget build(BuildContext context) {
    print(checkedItems.toString());
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Container(
        child: DropdownButton(
          onChanged: (i) => print("$i selected"),
          items: availableItems.map((e) => DropdownMenuItem(
            value: checkedItems.contains(e),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              children: [
              Text(e),
              Checkbox(
                  value: checkedItems.contains(e),
                  onChanged: (b) => setState(() {
                    b ?? false ? checkedItems.add(e) : checkedItems.remove(e);
                  }),),
            ],),
          ),
          ).toList(),
        ),
      ),
    );
  }
}

Can anyone tell me what is the problem here?

2

Answers


  1. The DropdownButton likely doesn’t update the view inside it when the setState is called.

    To fix this, you can use StatefulBuilder inside DropdownMenuItem. And return your Row widget for this widget builder function.

    DropdownButton(
              onChanged: (i) => print("$i selected"),
              items: availableItems
                  .map(
                    (e) => DropdownMenuItem(
                      value: checkedItems.contains(e),
                      child:
                          StatefulBuilder(builder: (context, StateSetter setStateNew) {
                        return Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            Text(e),
                            Checkbox(
                              value: checkedItems.contains(e),
                              onChanged: (b) {
                                setStateNew(() {
                                  b ?? false
                                      ? checkedItems.add(e)
                                      : checkedItems.remove(e);
                                });
                              },
                            ),
                          ],
                        );
                      }),
                    ),
                  )
                  .toList(),
            ),
    
    Login or Signup to reply.
  2. Try wrapping your Checkbox inside StatefulBuilder. If you want to update any state of a widget inside popup dialogue, for example: Dropdown, AlertDialogue etc, always wrap the content inside StatefulBuilder

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search