Search code examples
flutterdropdown

Flutter display DropDown Widget multiple times in different classes


I want to display the same dropdown on a different page. Now I get the error: There should be exactly one item with [DropdownButton]'s value: blue. Either zero or 2 or more [DropdownMenuItem]s were detected with the same value

This is my Dropdown class:

class DropDown extends StatelessWidget {
  late final String dropdownValue;
  final String itemsList;
  final TextEditingController textController;
  final List<String> categoryList = [
    "Hoodie",
    "Shoes",
    "Jeans",
    "Shirts",
  ];
  final List<String> colorList = [
    "pink",
    "red",
    "orange",
    "yellow",
    "lightgreen",
    "green",
    "turquise",
    "blue",
    "darkblue",
    "purple",
    "grey",
    "brown",
    "black",
    "white"
  ];

  DropDown(
      {required this.dropdownValue,
      required this.itemsList,
      required this.textController,
      Key? key})
      : super(key: key);

  Widget build(BuildContext context) {
    List<String> items;
    if (itemsList == "category") {
      items = categoryList;
    } else {
      items = colorList;
    }
    return DropdownButtonFormField<String>(
      value: dropdownValue,
      isExpanded: true,
      icon: const Icon(Icons.arrow_downward),
      elevation: 8,
      style: const TextStyle(color: Colors.grey, fontSize: 16),
      onChanged: (String? newValue) {
        dropdownValue = newValue!;
        textController.text = dropdownValue;
      },
      items: items.map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: dropdownValue,
          child: Padding(
              padding: const EdgeInsets.only(left: 12.0), child: Text(value)),
        );
      }).toList(),
    );
  }
}

I call it in my other classes like this:

 DropDown(
              dropdownValue: dropdownValueCategory,
              itemsList: "category",
              textController: categoryController
),

How can I display this Widget on different pages without this error? Thank you very much!


Solution

  • You need to create the stateful widget for dropdown. You need to pass the data to the dropdown class from the first class. I have created the demo, manage the className as your desire.

    Try as follows:

        class MyHomePage extends StatefulWidget {
      final String title;
    
      const MyHomePage({
        Key? key,
        required this.title,
      }) : super(key: key);
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
       final List<String> categoryList = [
        "Hoodie",
        "Shoes",
        "Jeans",
        "Shirts",
      ];
      final List<String> colorList = [
        "pink",
        "red",
        "orange",
        "yellow",
        "lightgreen",
        "green",
        "turquise",
        "blue",
        "darkblue",
        "purple",
        "grey",
        "brown",
        "black",
        "white"
      ];
      String catlistValue="";
      String  colorListValue="";
     void getDropDownValue(int i,String value){
        if(i==0){
          setState((){
            catlistValue=value;
          });
        }else{
           setState((){
            colorListValue=value;
          });
        }
      }
      
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body:Column(children:[
            MyStatefulWidget(
            data:categoryList,
                getValueFunc:getDropDownValue,
              identifier:0,
            ),
           Text(catlistValue),
             MyStatefulWidget(
            data:colorList,
               getValueFunc:getDropDownValue,
               identifier:1,
            ),
         Text(colorListValue)
          ])
          
          
      );
      }
    }
    

    MyStatefulWidget contains the the dropdown

        class MyStatefulWidget extends StatefulWidget {
       final data;
      final getValueFunc;
      final identifier;
      const MyStatefulWidget({Key? key,this.data,this.getValueFunc,this.identifier}) : super(key: key);
    
      @override
      State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
    }
    
    class _MyStatefulWidgetState extends State<MyStatefulWidget> {
      var dropdownValue ;
    
      @override
      Widget build(BuildContext context) {
        return DropdownButton<String>(
          value: dropdownValue,
          icon: const Icon(Icons.arrow_downward),
          elevation: 16,
          style: const TextStyle(color: Colors.deepPurple),
          underline: Container(
            height: 2,
            color: Colors.deepPurpleAccent,
          ),
          onChanged: (String? newValue) {
            setState(() {
              dropdownValue = newValue!;
            });
            widget.getValueFunc(widget.identifier,dropdownValue);
          },
          items:widget.data.map<DropdownMenuItem<String>>((String value) {
            return DropdownMenuItem<String>(
              value: value,
              child: Text(value),
            );
          }).toList(),
        );
      }
    }