应该只有一项具有 [DropdownButton] 的值:“合作伙伴”的实例

Posted

技术标签:

【中文标题】应该只有一项具有 [DropdownButton] 的值:“合作伙伴”的实例【英文标题】:There should be exactly one item with [DropdownButton]'s value: Instance of 'Partner' 【发布时间】:2021-11-05 20:11:04 【问题描述】:

我的下拉菜单按预期工作。但是当我选择一个项目时,我的应用程序因错误而崩溃

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

首先我在类中声明我的变量

    class _MultipleTestBookingState extends State<MultipleTestBooking> 

 Partner? _selectedLab;
 Datum? _selectedTest;
 ....................

使用Partner?_selectedLab; 声明,因为我的下拉菜单包含合作伙伴列表

然后使用这个变量在我的下拉列表中显示选定的值

 Container(
                  child: FutureBuilder<List<Partner>>(
                    future: AllPathLab(),
                    builder:
                        (BuildContext context, AsyncSnapshot snapshot) 
                      if (snapshot.connectionState !=ConnectionState.done) 
                        return CircularProgressIndicator();
                      
                      if (snapshot.hasError) 
                        return Text("Somthing went wrong");
                      

                      if (snapshot.hasData) 
                        return DropdownButton<Partner>(
                           value: _selectedLab,
                          hint: Text("Select Lab"),
                    items: snapshot.data.map((Partner data) =>
                    DropdownMenuItem<Partner>(
                                              child: Text("$data.partnerName"),
                                              value: data,
                                            )
                                            ).toList().cast<DropdownMenuItem<Partner>>(),
                      onChanged: (value)
                        setState(() 
                          _selectedLab=value;
                          encLabId = value!.encPartnerId;
                          GetTestByLab(); 
                        ); 

                      
                      
                      );
                          
                        
                      return Text("Waiting for Internet Connection");
                    ,
                  ),
                ),

Full code with my JSON response

【问题讨论】:

请检查您是否以正确的方式获取数据。如果可能,您可以添加 AllPathLab() 和 api 正在获取的示例 json 格式。 我相信我正在正确获取我的数据,因为单击下拉菜单会显示我来自 API 的所有数据。当我在 setState 中更改 _selectedLab 时出现错误。 我放了 My API fucntion 和我的 JSON response 的链接。你现在可以检查一下吗[gist.github.com/Roy-Tuhin/85dae5e908b21c92cb19a7f3c82dc0e7] 是的,我正在检查它,因为您有两个 api 点击您只提供了一个 json 示例,请同时提供并告诉我 哦!我的依赖下拉列表的第二个 api.. 我添加了名为 Get Test by Lab response [ gist.github.com/Roy-Tuhin/85dae5e908b21c92cb19a7f3c82dc0e7 ] 的 json 响应文件 【参考方案1】:

因此,根据您提供的数据,我创建了以下代码:

import 'package:date_time_picker/date_time_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/Patner.dart';
import 'package:flutter_app/dataModel.dart';
import 'package:http/http.dart' as http;

void main() 
  runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    home: MyApp(),
  ));


class MyApp extends StatefulWidget 
  const MyApp(Key key) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();


class _MyAppState extends State<MyApp> 
  Partner _selectedLab;
  Datum _selectedTest;
  Future getAllPathLabResults;
  Future getTestByLabResult;

  String encLabId = '';

  void initState() 
    super.initState();
    getAllPathLabResults = allPathLab();
    getTestByLabResult = getTestByLab();
  

  String _selectedDate = DateTime.now().toString();

  Future<List<Partner>> allPathLab() async 
    String jsonData = jsonstring;
    final model = modelFromJson(jsonData);
    print("This is the list length : $model.partner.length");

    List<Partner> arrData = model.partner;
    // this Future is for sample as you will be fetching the api data remove this one
    Future.delayed(Duration(seconds: 3));
    return arrData;
  

  Future<List<Datum>> getTestByLab() async 
    print("This is the Id :$encLabId");
    _selectedTest = null;
    var response = await http.post(
        Uri.parse("http://medbo.digitalicon.in/api/medboapi/GetTestByLab"),
        body: ("EncId": encLabId));

    if (response.statusCode == 200) 
      final dataModel = dataModelFromJson(response.body);
      print(dataModel.data.length);
      for (final item in dataModel.data) 
        print("This is hte test name :$item.testName");
      

      List<Datum> arrData = dataModel.data;
      return arrData;
    

    return [];
  

  @override
  Widget build(BuildContext context) 
    var screenWidth = MediaQuery.of(context).size.width;
    var screenHeight = MediaQuery.of(context).size.height;
    var blockSizeHorizontal = (screenWidth / 100);
    var blockSizeVertical = (screenHeight / 100);

    return Scaffold(
      body: SafeArea(
        child: Container(
          child: Column(
            children: [
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: ListTile(
                  title: Text("Booking Information",
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                        fontSize: blockSizeHorizontal * 5,
                        fontFamily: 'Poppins',
                        color: Theme.of(context).primaryColor,
                      )),
                  subtitle: Text("Preferred Visit Date"),
                ),
              ),
              Container(
                margin: EdgeInsets.only(left: 20),
                padding: EdgeInsets.only(left: 0, right: 150),
                decoration: BoxDecoration(
                  color: Colors.lightBlue[50],
                  borderRadius: BorderRadius.all(Radius.circular(12)),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: DateTimePicker(
                    initialValue: DateTime.now().toString(),
                    //initialValue:'', // initialValue or controller.text can be null, empty or a DateTime string otherwise it will throw an error.
                    type: DateTimePickerType.date,
                    dateLabelText: 'Select Date',
                    style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: blockSizeHorizontal * 3.5,
                      fontFamily: 'Poppins',
                      color: Colors.green,
                      letterSpacing: 2.0,
                    ),
                    firstDate: DateTime.now(),
                    lastDate: DateTime.now().add(Duration(days: 30)),
                    // This will add one year from current date
                    validator: (value) 
                      return null;
                    ,
                    onChanged: (value) 
                      if (value.isNotEmpty) 
                        setState(() 
                          _selectedDate = value;
                        );
                      
                    ,
                    onSaved: (value) 
                      if (value.isNotEmpty) 
                        _selectedDate = value;
                      
                    ,
                  ),
                ),
              ),

              ListTile(
                title: Text(
                  "Select Pathological Lab",
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: blockSizeHorizontal * 4.0,
                    fontFamily: 'Poppins',
                    color: Theme.of(context).primaryColor,
                  ),
                ),
              ),

              Container(
                child: FutureBuilder<List<Partner>>(
                  future: getAllPathLabResults,
                  builder: (BuildContext context, AsyncSnapshot snapshot) 
                    if (snapshot.connectionState != ConnectionState.done) 
                      return CircularProgressIndicator();
                    
                    if (snapshot.hasError) 
                      return Text("Somthing went wrong");
                    

                    if (snapshot.hasData) 
                      List<Partner> data =
                          snapshot.hasData ? snapshot.data : [];
                      return DropdownButton<Partner>(
                        value: _selectedLab,
                        hint: Text("Select Lab"),
                        //underline: SizedBox(),
                        //isExpanded: true,
                        items: data
                            .map((Partner data) => DropdownMenuItem<Partner>(
                                  child: Text("$data.partnerName"),
                                  value: data,
                                ))
                            .toList()
                            .cast<DropdownMenuItem<Partner>>(),
                        onChanged: (value) 
                          setState(() 
                            _selectedLab = value;

                            encLabId = value.encPartnerId;
                            getTestByLabResult = getTestByLab();
                          );
                          //GetTestByLab(value!.encPartnerId); // passing encid to my next API function
                          // GetTestByLab();
                        ,
                      );
                    
                    return Text("Waiting for Internet Connection");
                  ,
                ),
              ),

              //=========================================================== Dependent drop down===================================

              ListTile(
                title: Text(
                  "Test Name",
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: blockSizeHorizontal * 4.0,
                    fontFamily: 'Poppins',
                    color: Theme.of(context).primaryColor,
                  ),
                ),
              ),

              Container(
                child: FutureBuilder<List<Datum>>(
                  future: getTestByLabResult,
                  builder: (BuildContext context, AsyncSnapshot snapshot) 
                    if (snapshot.connectionState != ConnectionState.done) 
                      return CircularProgressIndicator();
                    
                    if (snapshot.hasError) 
                      return Text("Select a Lab for your Test");
                    

                    if (snapshot.hasData) 
                      List<Datum> data = snapshot.hasData ? snapshot.data : [];

                      return DropdownButton<Datum>(
                          value: _selectedTest,
                          hint: Text(""),
                          //underline: SizedBox(),
                          //isExpanded: true,
                          items: data
                              .map((Datum data) => DropdownMenuItem<Datum>(
                                    child: Text("$data.testName"),
                                    value: data,
                                  ))
                              .toList()
                              .cast<DropdownMenuItem<Datum>>(),
                          onChanged: (value) 
                            print("This is the value : $value.testName");
                            setState(() 
                              _selectedTest = value;
                            );
                            //GetTestByLab(value!.encPartnerId); // passing encid to my next API function
                          );
                    
                    return Text("Waiting for Internet Connection");
                  ,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  


// used this as a sample 
String jsonstring = '''
  "Status": "1",
  "Message": "",
  "Partner": [
    
      "EncPartnerId": "IujyQXg8KZg8asLvK/FS7g==",
      "PartnerName": "dasfdsf"
    ,
    
      "EncPartnerId": "pEl2B9kuumKRxIxLJO76eQ==",
      "PartnerName": "partner172"
    ,
    
      "EncPartnerId": "eYwtNBXR6P/JDtsIwr+Bvw==",
      "PartnerName": "nnkb"
    ,
    
      "EncPartnerId": "kFgorcFF0G6RQD4W+LwWnQ==",
      "PartnerName": "nnkjj"
    ,
    
      "EncPartnerId": "U4exk+vfMGrn7cjNUa/PBw==",
      "PartnerName": "mahadev"
    ,
    
      "EncPartnerId": "tqkaSjTFgDf0612mp9mbsQ==",
      "PartnerName": null
    ,
    
      "EncPartnerId": "0aruO0FbYOu5IerRBxdT8w==",
      "PartnerName": "Suraksha Diagnostics"
    ,
    
      "EncPartnerId": "65gtodyhbtdInTsJWr1ZkA==",
      "PartnerName": "Rasomoy pvt. Hospital"
    ,
    
      "EncPartnerId": "LEuT1eIlpLEMAAkZme3wpQ==",
      "PartnerName": "Tangra medical House"
    ,
    
      "EncPartnerId": "q8O8YMzYKXSB4RtkX4k7Lw==",
      "PartnerName": "Partner new"
    
  ]
''';

API 模型:

// To parse this JSON data, do
//
//     final model = modelFromJson(jsonString);

import 'dart:convert';

Model modelFromJson(String str) => Model.fromJson(json.decode(str));

String modelToJson(Model data) => json.encode(data.toJson());

class Model 
  Model(
    this.status,
    this.message,
    this.partner,
  );

  String status;
  String message;
  List<Partner> partner;

  factory Model.fromJson(Map<String, dynamic> json) => Model(
        status: json["Status"],
        message: json["Message"],
        partner:
            List<Partner>.from(json["Partner"].map((x) => Partner.fromJson(x))),
      );

  Map<String, dynamic> toJson() => 
        "Status": status,
        "Message": message,
        "Partner": List<dynamic>.from(partner.map((x) => x.toJson())),
      ;


class Partner 
  Partner(
    this.encPartnerId,
    this.partnerName,
  );

  String encPartnerId;
  String partnerName;

  factory Partner.fromJson(Map<String, dynamic> json) => Partner(
        encPartnerId: json["EncPartnerId"],
        partnerName: json["PartnerName"] == null ? null : json["PartnerName"],
      );

  Map<String, dynamic> toJson() => 
        "EncPartnerId": encPartnerId,
        "PartnerName": partnerName == null ? null : partnerName,
      ;



第二个api解析模型

// To parse this JSON data, do
//
//     final dataModel = dataModelFromJson(jsonString);

import 'dart:convert';

DataModel dataModelFromJson(String str) => DataModel.fromJson(json.decode(str));

String dataModelToJson(DataModel data) => json.encode(data.toJson());

class DataModel 
  DataModel(
    this.status,
    this.message,
    this.data,
  );

  String status;
  String message;
  List<Datum> data;

  factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
        status: json["Status"],
        message: json["Message"],
        data: json["Data"] == null
            ? []
            : List<Datum>.from(json["Data"].map((x) => Datum.fromJson(x))),
      );

  Map<String, dynamic> toJson() => 
        "Status": status,
        "Message": message,
        "Data":
            data == null ? [] : List<dynamic>.from(data.map((x) => x.toJson())),
      ;


class Datum 
  Datum(
    this.testId,
    this.encTestId,
    this.testName,
    this.noOfPartner,
    this.testFee,
    this.discountedFee,
    this.bookingFee,
    this.reportTime,
    this.note,
    this.createBy,
    this.createDate,
    this.modBy,
    this.modDate,
    this.activeStatus,
    this.permission,
  );

  String testId;
  dynamic encTestId;
  String testName;
  dynamic noOfPartner;
  dynamic testFee;
  dynamic discountedFee;
  dynamic bookingFee;
  dynamic reportTime;
  dynamic note;
  dynamic createBy;
  dynamic createDate;
  dynamic modBy;
  dynamic modDate;
  dynamic activeStatus;
  dynamic permission;

  factory Datum.fromJson(Map<String, dynamic> json) => Datum(
        testId: json["TestId"],
        encTestId: json["EncTestId"],
        testName: json["TestName"],
        noOfPartner: json["NoOfPartner"],
        testFee: json["TestFee"],
        discountedFee: json["DiscountedFee"],
        bookingFee: json["BookingFee"],
        reportTime: json["ReportTime"],
        note: json["Note"],
        createBy: json["CreateBy"],
        createDate: json["CreateDate"],
        modBy: json["ModBy"],
        modDate: json["ModDate"],
        activeStatus: json["ActiveStatus"],
        permission: json["Permission"],
      );

  Map<String, dynamic> toJson() => 
        "TestId": testId,
        "EncTestId": encTestId,
        "TestName": testName,
        "NoOfPartner": noOfPartner,
        "TestFee": testFee,
        "DiscountedFee": discountedFee,
        "BookingFee": bookingFee,
        "ReportTime": reportTime,
        "Note": note,
        "CreateBy": createBy,
        "CreateDate": createDate,
        "ModBy": modBy,
        "ModDate": modDate,
        "ActiveStatus": activeStatus,
        "Permission": permission,
      ;


因此,当您最初根据 id 获取数据并选择第二个下拉菜单时。现在,当您更改实验室时,您可以将所选文本设为空。 而且您还以错误的方式使用了futurebuilder方法,因为调用了setstate它正在创建多个rebuids并给出错误。

请运行代码并检查其是否正常工作。

【讨论】:

好的,正在尝试!快速提问:我可以从 Api 获取我的Lab 数据吗? Future&lt;List&lt;Partner&gt;&gt; allPathLab() async String jsonData = jsonstring; 当我们通过 api 调用获取 Test 的数据时 目前上面的代码是用来从字符串中获取你提供的json,使用你提供的gist中的代码,它不会改变。 进行 api 调用检查 200 成功,然后从 response.body 获取数据,将其添加到最后一个模型 = modelFromJson(response.body);

以上是关于应该只有一项具有 [DropdownButton] 的值:“合作伙伴”的实例的主要内容,如果未能解决你的问题,请参考以下文章

Flutter GetBuilder Dependent DropDownButton - 即使值已被重置,也应该只有一项具有 [DropdownButton] 的值

下拉值不能设置为空

Flutter DropdownButton 颜色与父 Widgets 相同

如何在颤动中手动显示/关闭 DropdownButton?

“没有引用声明‘setState’。” StatefulWidget 中 DropdownButton 的警告

Flutter - DropdownButton 溢出