Home > Mobile >  I am trying to get Object item list to the Custom drop down menu but there is an error. Flutter
I am trying to get Object item list to the Custom drop down menu but there is an error. Flutter

Time:04-12

I am trying to get Course List Object to the custom dropdown menu items but i am encountring an error like that

""There should be exactly one item with [DropdownButton]'s value: Instance of 'Course'. Either zero or 2 or more [DropdownMenuItem]s were detected with the same value""

How can I fix this. Could u please help me?

import 'package:flutter/material.dart';
import 'package:internship_managing_system/model/Course.dart';
import 'package:internship_managing_system/student/widgets/widgets.dart';

import '../../shared/constants.dart';

class DropDownCourses extends StatefulWidget {
  List<Course> itemList;
  String hintText;

  DropDownCourses(this.itemList, this.hintText, {Key? key}) : super(key: key);

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

class _DropDownCoursesState extends State<DropDownCourses> {
  printList() {
    for (int i = 0; i < widget.itemList.length; i  ) {
      print(widget.itemList[i]);
    }
  }

  Course? dropdownValue;
  @override
  void initState() {
    super.initState();
    dropdownValue = Course(id: 1, courseName: "C1");
  }

  @override
  Widget build(BuildContext context) {
    List<Course> courseList = <Course>[
      Course(id: 1, courseName: "C1"),
      Course(id: 2, courseName: "C2"),
      Course(id: 3, courseName: "C3")
    ];
    return Container(
      margin: const EdgeInsets.all(4),
      child: Column(
        children: [
          Text(
            widget.hintText,
            style: TEXT_STYLE,
          ),
          Padding(
            padding: const EdgeInsets.all(PADDING_VALUE),
            child: Container(
              height: 50,
              decoration: BoxDecoration(
                  color: Colors.grey[700],
                  borderRadius: BorderRadius.circular(5)),
              child: DropdownButton<Course>(
                /*  decoration: const InputDecoration(border: InputBorder.none),
                isExpanded: true,
                validator: (val) =>
                    val == null ? 'Lütfen ${widget.hintText} giriniz' : null,*/
                value: dropdownValue,
                icon: const Icon(
                  Icons.arrow_downward,
                  color: ICON_COLOR,
                ),
                iconSize: 24,
                elevation: 16,
                dropdownColor: Colors.grey[800],
                style: TEXT_STYLE,
                onChanged: (Course? val) {
                  setState(() {
                    dropdownValue = val!;
                  });
                },
                items:
                    courseList.map<DropdownMenuItem<Course>>((Course course) {
                  return DropdownMenuItem<Course>(
                    value: course,
                    child: Center(
                      //TODO: Liste türünü kontrol et
                      child: Text(
                        course.courseName,
                        style: TEXT_STYLE,
                      ),
                    ),
                  );
                }).toList(),
              ),
            ),
          )
        ],
      ),
    );
  }
}

CodePudding user response:

Here an example of the solution, added comments for each line to change, you have to pass a String value to the dropdown value property not the full Course class:

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DropDownCourses(),
    );
  }
}

class DropDownCourses extends StatefulWidget {

  DropDownCourses({Key? key}) : super(key: key);

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

class _DropDownCoursesState extends State<DropDownCourses> {

  String? dropdownValue = "C1"; // 1- change this to be only a String type variable
  List<Course> courseList = <Course>[
    Course(id: 1, courseName: "C1"),
    Course(id: 2, courseName: "C2"),
    Course(id: 3, courseName: "C3")
  ];

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      body: Container(
        margin: const EdgeInsets.all(4),
        child: Column(
          children: [
            Padding(
              padding: const EdgeInsets.all(10),
              child: Container(
                height: 50,
                decoration: BoxDecoration(
                    color: Colors.grey[700],
                    borderRadius: BorderRadius.circular(5)),
                child: DropdownButton<String>(  // 2- also here change to only accept String values
                  value: dropdownValue,
                  icon: const Icon(
                    Icons.arrow_downward,
                    color: Colors.pink,
                  ),
                  iconSize: 24,
                  elevation: 16,
                  dropdownColor: Colors.grey[800],
                  onChanged: (String? val) { // 3- the value pass should also be String
                    setState(() {
                      dropdownValue = val!;
                    });
                  },
                  items:
                  courseList.map<DropdownMenuItem<String>>((Course course) {
                    return DropdownMenuItem<String>(
                      value: course.courseName, // 4- and here pass the courseName since it will be the String to be used in the drop down
                      child: Center(
                        child: Text(
                          course.courseName!,
                        ),
                      ),
                    );
                  }).toList(),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

class Course {

  int? id;
  String? courseName;

  Course({ this.id, this.courseName });

}
  • Related