Либо ноль, либо 2 или более [DropdownMenuItem] были обнаружены с одинаковым значением - PullRequest
1 голос
/ 27 января 2020

Я новичок во Flutter, но я пытаюсь создать DropdownButtonFormField, и он не работает. Я получаю ошибку, которая говорит, что у меня есть повторяющиеся значения. Что интересно, у меня нет списка с дублирующимися значениями. Я нашел аналогичный вопрос о SO, и в решении говорится, что нужно инициировать строки со значением и что пользователь дублировал элемент списка, но у меня есть похожее решение для другого другого списка, и, похоже, он работает нормально. Я не могу понять, почему это не работает здесь. Любая помощь приветствуется.

Сообщение об ошибке:

There should be exactly one item with [DropdownButton]'s value: 0. 
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
'package:flutter/src/material/dropdown.dart':
Failed assertion: line 1411 pos 15: 'items == null || items.isEmpty || value == null ||
              items.where((DropdownMenuItem<T> item) {
                return item.value == value;
              }).length == 1'
The relevant error-causing widget was: 
  StreamBuilder<UserProfile>

ProfileForm Class:

final List<String> accountType = ['Educator', 'School Administrator', 'Parent'];

  String _currentAccountType;

  @override
  Widget build(BuildContext context) {
    final user = Provider.of<User>(context);
    return StreamBuilder<UserProfile>(
        stream: DatabaseService(uid: user.uid).userProfileData,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            UserProfile userProfileData = snapshot.data;
            return Form(
              key: _formKey,
              child: Column(
                children: <Widget>[
                  SizedBox(height: 20.0),
                  DropdownButtonFormField(
                    decoration: textInputDecoration,
                    value: _currentAccountType ?? userProfileData.accountType,
                    items: accountType.map((accountType) {
                      return DropdownMenuItem(
                        value: accountType,
                        child: Text(accountType),
                      );
                    }).toList(),
                    onChanged: (val) {
                      setState(() {
                        _currentAccountType = val;
                      });
                    },
                  ),

База данных класса

class DatabaseService {
  final String uid;
  DatabaseService({this.uid});

  final CollectionReference userProfileCollection =
      Firestore.instance.collection('user_profile');

  Future updateUserProfile(
      String accountType,
      String birthDate,
      String courseName,
      String dateJoined,
      String email,
      String firstName,
      String lastName,
      String schoolName,
      String title) async {
    return await userProfileCollection.document(uid).setData({
      'accountType': accountType,
      'birthDate': birthDate,
      'courseName': courseName,
      'dateJoined': dateJoined,
      'email': email,
      'firstName': firstName,
      'lastName': lastName,
      'schoolName': schoolName,
      'title': title,
    });
  }

  //User Profile from snapshot
  List<Profile> _userProfileListFromSnapshot(QuerySnapshot snapshot) {
    return snapshot.documents.map((doc) {
      return Profile(
        accountType: doc.data['accountType'] ?? '',
        birthDate: doc.data['birthDate'] ?? '',
        courseName: doc.data['courseName'] ?? '',
        dateJoined: doc.data['dateJoined'] ?? '',
        email: doc.data['email'] ?? '',
        firstName: doc.data['firstName'] ?? '',
        lastName: doc.data['lastName'] ?? '',
        schoolName: doc.data['schoolName'] ?? '',
        title: doc.data['title'] ?? '',
      );
    }).toList();
  }

  UserProfile _userProfileFromSnapshot(DocumentSnapshot snapshot) {
    return UserProfile(
      uid: uid,
      accountType: snapshot.data['accountType'],
      birthDate: snapshot.data['birthDate'],
      courseName: snapshot.data['courseName'],
      dateJoined: snapshot.data['dateJoined'],
      email: snapshot.data['email'],
      firstName: snapshot.data['firstName'],
      lastName: snapshot.data['lastName'],
      schoolName: snapshot.data['schoolName'],
      title: snapshot.data['title'],
    );
  }

  Stream<List<Profile>> get userProfile {
    return userProfileCollection.snapshots().map(_userProfileListFromSnapshot);
  }

  Stream<UserProfile> get userProfileData {
    return userProfileCollection
        .document(uid)
        .snapshots()
        .map(_userProfileFromSnapshot);
  }
}

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

В моем случае изменение ниже разрешило ошибку:

Сценарий ошибки:

var itemList=['Alpha','Beta','Cat'];
var itemSelected='Zebra';

Рабочий сценарий:

var itemList=['Alpha','Beta','Cat'];
var itemSelected='Cat'; //Can be Alpha, Beta or Cat but not any other value

Код раскрывающегося виджета:

DropdownButton<String>(
                    items: itemList.map((String singleItem){
                          return DropdownMenuItem<String>(
                            value: singleItem,
                            child:Text(singleItem)
                          );
                    }).toList(),

                    onChanged: (String itemChosen){
                      setState(() {
                        this.itemSelected=itemChosen;
                      });
                    },
                   value:itemSelected ,

                  ),

Наличие значения переменной itemSelected, равного одному из элементов в списке, решило проблему для меня.

1 голос
/ 27 января 2020

userProfileData.accountType имеет значение «0», а не «Педагог», «Администратор школы» или «Родитель».

Успех: значение обязательно в items.value

 final List<String> accountType = ['Educator', 'School Administrator', 'Parent'];

 DropdownButtonFormField(
                    decoration: textInputDecoration,
                    value: accountType[0],
                    items: accountType.map((accountType) {
                      return DropdownMenuItem(
                        value: accountType,
                        child: Text(accountType),
                      );
                    }).toList(),
                    onChanged: (val) {
                      setState(() {
                        _currentAccountType = val;
                      });
                    },
                  ),

Ошибка: Должен быть ровно один элемент со значением [DropdownButton]: хахаха

 final List<String> accountType = ['Educator', 'School Administrator', 'Parent'];

 DropdownButtonFormField(
                    decoration: textInputDecoration,
                    value: 'hahaha',
                    items: accountType.map((accountType) {
                      return DropdownMenuItem(
                        value: accountType,
                        child: Text(accountType),
                      );
                    }).toList(),
                    onChanged: (val) {
                      setState(() {
                        _currentAccountType = val;
                      });
                    },
                  ),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...