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 1: Can Karabag

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: &lt;Widget&gt;[
      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) =&gt; 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;
                },
              )


Solution 2: User09061968

I changed the value of the dropdown var to 1 initially var _value = '1'; So when the dropdown button has to display its value it displays the one whose value I have set 1 as in the items list in DropDownButton

DropdownButton(
                underline: Container(),
                onChanged: (value) {
                  setState(() {
                    _value = value;
                  });
                },
                value: _value,
                items: [
                  DropdownMenuItem(
                    value: "1",
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        Icon(MaterialCommunityIcons.devices),
                        SizedBox(width: 10),
                        Text(
                          "Consumption",
                          style: TextStyle(
                              fontSize: 18.0, fontWeight: FontWeight.w600),
                        ),
                      ],
                    ),
                  ),
                  DropdownMenuItem(
                    value: "2",
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        Icon(MaterialCommunityIcons.solar_panel),
                        SizedBox(width: 10),
                        Text(
                          "Generation",
                          style: TextStyle(
                              fontSize: 18.0, fontWeight: FontWeight.w600),
                        ),
                      ],
                    ),
                  ),
                ],
              ),


Solution 3: alabra

You need implement "equals" in class AssignedWorkspace. I used equatable package.

Example class AssignedWorkspace

class AssignedWorkspace extends Equatable {
  final String id;
  final String name;

  AssignedWorkspace(this.id, this.name);

  @override
  List<Object> get props => [id];
}


Solution 4: sandeep gurram

For me id of one of the element is null, once added id is made non-null issue got fixed.


Solution 5: ack ismayil

if you want to see only an initial value you can use hint text named parameter of drop down button and set a text widget. i dont know whether it is a good practice or not.