Flutter - Dropdown - Items - Disable?

Viewed 3460

I discovered the DropdownButton Widget in Flutter and I played around with the items.My question is now, why is there no option to disable an item in the dropdownmenuitem widget? Or is there a way to do it?

My Idea was that I have multiple dropdowns with the same itemList and if I choose one item in an dropdown it should be disabled in the other ones. Any Idea?

3 Answers

https://dartpad.dev/d2b1688b14270bdf56ae952adfac93d2

there is no official way to disable some DropdownMenuItem but you can simulate this by not selecting the disabled item when selected and by changing its color. otherwise, you would need to copy DropdownButton and add this capability yourself.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: Center(
          child: MyStatefulWidget(),
        ),
      ),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  MyStatefulWidget({Key key}) : super(key: key);

  @override
  _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  final disabledItems  = ['Free', 'Four'];

  String dropdownValue = 'One';

  @override
  Widget build(BuildContext context) {
    return DropdownButton<String>(
      value: dropdownValue,
      icon: Icon(Icons.arrow_downward),
      iconSize: 24,
      elevation: 16,
      style: TextStyle(color: Colors.deepPurple),
      underline: Container(
        height: 2,
        color: Colors.deepPurpleAccent,
      ),
      onChanged: (String newValue) {
        if (!disabledItems.contains(newValue)) {
          setState(() {
            dropdownValue = newValue;
          });
        }
      },
      items: <String>['One', 'Two', 'Free', 'Four']
          .map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(
            value,
            style: TextStyle(
              color: disabledItems.contains(value) ? Colors.grey : null,
            ),
          ),
        );
      }).toList(),
    );
  }
}

Just try this:

return DropdownButtonFormField(
      value: dropValue,
      items: DropItems.map((String value) {
        if (value == "a") {
          return DropdownMenuItem<String>(
            child: Text(value, style: const TextStyle(color: Colors.grey)),
            value: value,
            onTap: () => null,
            enabled: false, // disable this item
          );
        }
        return DropdownMenuItem<String>(child: Text(value), value: value);
      }).toList(),
      onTap: (){
           // some code
      },
      onChanged: (){
           // some code
      },
    );
)

A slightly different version:

Creates all the items, but the ones which must be disabled have onTap => null && Color = grey.

You can merge this solution with @humazed's, to check if an element is contained inside an exclusion list.


String selectedValue;

...

 DropdownButtonFormField(
            decoration: InputDecoration(
                icon: const Icon(Icons.category),
                labelText: 'Disabled dropdown menu'),
            items: ['a', 'b', 'c'].map((value) {
              // normal options
              if (value != 'c') {
                return DropdownMenuItem<String>(
                  value: value,
                  child: new Text(value,
                      style: new TextStyle(color: Colors.black)),
                );
              // the disabled one ("c") 
              } else {
                return DropdownMenuItem<String>(
                  child: Text(value, style: TextStyle(color: Colors.grey)),
                  onTap: () => null,
                );
              }
            }).toList(),
            value: selectedValue,
            onChanged: (String newValue) {
              setState(() {
                selectedValue = newValue;
              });
            },
          ),

Wouldn't be nice to set onTap() => null and have the menu option already disabled? Like a disabled button works. I've sent an improvement request on Flutter's github

Related