78

I wanted to control a drop-down button and make it unclickable using a button.

Is there any way to make it disable. Basically not allowing it able to change.

new DropdownButton(
          value: animalName,
          items: animals.map(
            (String value) {
              return new DropdownMenuItem<String>(
                value: value,
                child: new Text('$value'),
              );
            },
          ).toList(),
          onChanged: (value) {
            setState(() {
              animalName = value;
            });
          },
        ),

So this is the code I currently use on the drop-down button, but i cant disabled it.

0

10 Answers 10

203

Found this in the DropdownButton docs:

If items or onChanged is null, the button will be disabled, the down arrow will be grayed out, and the disabledHint will be shown (if provided)

DropdownButton(
  onChanged: null,
  items: [...],
)
Sign up to request clarification or add additional context in comments.

1 Comment

Awsome! It would be much better if there was an "enabled" constructor parameter.
29

This isn't what you want to hear, but I don't think there's currently an easy way. I experimented with simply removing all the items and that causes a nice little crash. Maybe worth raising an issue with the flutter people on github...

There is an alternative that may be good enough for you for now. If you wrap your DropdownButton in an IgnorePointer, when you want it to be disabled you can change IgnorePointer's ignoring property to true.

That way if the user taps on it, it won't do anything.

But you'll probably want to indicate to the user somehow that it's disabled as well, something like setting the hint text (as it's grey).

      child: new IgnorePointer(
        ignoring: true,
        child: new DropdownButton(
          hint: new Text("disabled"),
            items: ["asdf", "wehee", "asdf2", "qwer"].map(
              (String value) {
                return new DropdownMenuItem<String>(
                  value: value,
                  child: new Text('$value'),
                );
              },
            ).toList(),
          onChanged: (value) {},
        ),

Comments

15

You can make DropdownButtonFormField or DropdownButton disabled if set onChanged to null, and if you want that dropdown still shows selected value you must set disabledHint. For example:

     DropdownButtonFormField<String>(
        disabledHint: Text(_selectedItem),
        value: _selectedItem,
        onChanged: enabled ? (value) => setState(() => _selectedItem = value) : null,
        items: items.map<DropdownMenuItem<String>>((item) {
          return DropdownMenuItem(
            value: item,
            child: Text(item),
          );
        }).toList(),
      )

Comments

14

Just wrap it with IgnorePointer widget to make DropdownButton disable

IgnorePointer(
      ignoring:  enabled,
      child: new DropdownButton(
          value: animalName,
          items: animals.map(
            (String value) {
              return new DropdownMenuItem<String>(
                value: value,
                child: new Text('$value'),
              );
            },
          ).toList(),
          onChanged: (value) {
            setState(() {
              animalName = value;
            });
          },
        ),
);

Comments

4

If items or onChanged is null, the button will be disabled, the down arrow will be grayed out, and the disabledHint will be shown (if provided)

So something like this should work:

DropdownButton<String>(
  ...
  onChanged: this.enabled ? (id) => setState(() => this.id = id) : null,
)

1 Comment

problem with this is that if disabled, the value property does not reflect and selects it by default
3

okay, i found a trick that satisfied me i wanted it hide/show the DropdownButton depending on CheckboxListTile

in StatefulWidget Class first create a function ex:

  _buildDropDown(bool enable) {
    if (enable) {
      return DropdownButton<String>(
        hint: Text("Hint"),
        items: <String>[
          'item 1',
          'item 2',
          'item 3',
        ].map((String value) {
          return new DropdownMenuItem<String>(
            value: value,
            child: new Text(value),
          );
        }).toList(),
        onChanged: (value) {},
      );
    } else { // Just Divider with zero Height xD
      return Divider(color: Colors.white, height: 0.0);
    }
  }

and now in build

bool enable = true;

@override
Widget build(BuildContext context) {
  return Column(
    children: <Widget>[
      CheckboxListTile(
        title: const Text('Switcher'),
        selected: true,
        value: enable,
        onChanged: (bool value) {
          setState(() {
            enable = value;
          });
        },
      ),
      _buildDropDown(enable),
    ],
  );
}

now every time you change enable it will display and hide the DropdownButton

1 Comment

Just return an empty Container, e.g. return Container();
3
DropdownButtonFormField(
     onChange: isDisable ? null : (str){
        
     },
     disabledHint: isDisable ?  null : Text('Your hint text'),
     ...
)

For disable onChange: null

For disable Caption disabledHint: Text('Your hint text')

1 Comment

disable hint should be with NOT disabledHint: !isDisable ? null : Text('Your hint text'),
0

//add widget'AbsorbPointer' true-disable,false-enable

// isEditable = ture

AbsorbPointer(
    absorbing: isEditable
    DropdownButton(
    onChanged: null,
    items: [...],
    )
)

Comments

0

do like this term : just do a trinary statement to the items array like this

DropdownButtonFormField<String>(
  dropdownColor: Colors.black,

  style: TextStyle(color: Colors.white), // Text color

  decoration: InputDecoration(
    labelStyle: TextStyle(color: Colors.white),
    labelText: "اختر ",
    border: OutlineInputBorder(),
  ),
  //van or sedan pickup_truck coupe mini_van cross_over city_car
  items: useOtherCar == true
      ? [
          DropdownMenuItem<String>(
            value: DriversCarCubit.get(context).CarTypeController.text,
            child: Text(
              DriversCarCubit.get(context).CarTypeController.text,
              style: TextStyle(color: Colors.white),
            ),
          )
        ]
      : [
          'van',
          'sedan',
          'pickup_truck',
          'coupe',
          'mini_van',
          'cross_over',
          'city_car'
        ].map((String value) {
          return DropdownMenuItem<String>(
            value: value,
            child: Text(
              value,
              style: TextStyle(color: Colors.white),
            ),
          );
        }).toList(),
  value: DriversCarCubit.get(context).CarTypeController.text ?? 'sedan',
  onChanged: (newValue) {
    setState(() {
      DriversCarCubit.get(context).CarTypeController.text =
          newValue.toString();
    });
  },
);

Comments

-1

Simple:

decoration:InputDecoration(enabled: false),

1 Comment

decoration does not exist for DropDownButton.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.