Search code examples
flutterdropdowndefault-valuedropdownbutton

Set default value for dropdown button in flutter


I have a dropdown button which works fine, but when I try to set a default value it will fail with the following error:

'package:flutter/src/material/dropdown.dart': Failed assertion: line 620 pos 15: 'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem item) => item.value == value).length == 1': is not true.

This is my dropdown button:

 Widget changeWorkspace() {
return StatefulBuilder(
    builder: (BuildContext context, StateSetter setState) {
  return Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
    Padding(
      padding: EdgeInsets.all(8.0),
      child: DropdownButton<AssignedWorkspace>(
          isExpanded: true,
          hint: Text("SELECT WORKSPACE"),
          value: selectedWorkspace,
          onChanged: (dropdownValueSelected) {
            setState(() {
              selectedWorkspace = dropdownValueSelected;
            });
          },
          items: workspaces != null && workspaces.length > 0
              ? workspaces.map((AssignedWorkspace workspace) {
                  return new DropdownMenuItem<AssignedWorkspace>(
                    value: workspace,
                    child: new Text(workspace.name,
                        style: new TextStyle(color: Colors.black)),
                  );
                }).toList()
              : null),
    ),
  ]);
});

}

I've tried to set the value of selectedWorkspace onInit as follows but it fails.

selectedWorkspace = new AssignedWorkspace(
id: userSettings.currentWorkspaceId,
name: userSettings.currentWorkspaceName);

Is there a way of setting a default value in a dropdown button?


Solution

  • import 'package:flutter/material.dart';
    
    import '../config/app_theme.dart';
    
    class DropdownWidget extends StatefulWidget {
      final String title;
      final List<String> items;
      final ValueChanged<String> itemCallBack;
      final String currentItem;
      final String hintText;
    
      DropdownWidget({
        this.title,
        this.items,
        this.itemCallBack,
        this.currentItem,
        this.hintText,
      });
    
      @override
      State<StatefulWidget> createState() => _DropdownState(currentItem);
    }
    
    class _DropdownState extends State<DropdownWidget> {
      List<DropdownMenuItem<String>> dropDownItems = [];
      String currentItem;
      AppTheme appTheme;
    
      _DropdownState(this.currentItem);
    
      @override
      void initState() {
        super.initState();
        for (String item in widget.items) {
          dropDownItems.add(DropdownMenuItem(
            value: item,
            child: Text(
              item,
              style: TextStyle(
                fontSize: 16,
              ),
            ),
          ));
        }
      }
    
      @override
      void didUpdateWidget(DropdownWidget oldWidget) {
        if (this.currentItem != widget.currentItem) {
          setState(() {
            this.currentItem = widget.currentItem;
          });
        }
        super.didUpdateWidget(oldWidget);
      }
    
      @override
      Widget build(BuildContext context) {
        appTheme = AppTheme(Theme.of(context).brightness);
    
        return Container(
          margin: EdgeInsets.symmetric(vertical: 10),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Container(
                margin: EdgeInsets.only(left: 6),
                child: Text(
                  widget.title,
                  style: appTheme.activityAddPageTextStyle,
                ),
              ),
              Container(
                padding: EdgeInsets.symmetric(vertical: 3, horizontal: 15),
                margin: EdgeInsets.only(top: 10),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(6),
                  color: Colors.white,
                  boxShadow: [
                    BoxShadow(
                      offset: Offset(0, 2),
                      blurRadius: 10,
                      color: Color(0x19000000),
                    ),
                  ],
                ),
                child: DropdownButtonHideUnderline(
                  child: DropdownButton(
                    icon: appTheme.activityAddPageDownArrowSVG,
                    value: currentItem,
                    isExpanded: true,
                    items: dropDownItems,
                    onChanged: (selectedItem) => setState(() {
                      currentItem = selectedItem;
                      widget.itemCallBack(currentItem);
                    }),
                    hint: Container(
                      child: Text(widget.hintText, style: appTheme.hintStyle),
                    ),
                  ),
                ),
              ),
            ],
          ),
        );
      }
    }
    

    This is my dropDownWidget without optimization. It has currentItem. You could use it like:

               DropdownWidget(
                    title: kStatus,
                    items: state.customerStepInfo.statusList,
                    currentItem: status,
                    hintText: kCommonPick,
                    itemCallBack: (String status) {
                      this.status = status;
                    },
                  )