java 导航至带有下拉菜单的屏幕两次,出现以下错误:检测到零个或两个或多个具有相同值的[DropdownMenuItem]

kse8i1jr  于 2023-03-16  发布在  Java
关注(0)|答案(1)|浏览(117)

我知道这个错误的原因,但是我在这种情况下找不到原因。下面是一个场景,当我第一次导航到包含下拉菜单的屏幕时,下拉菜单工作正常。但是,当我返回并重新导航到同一个屏幕(第二次)时,抛出了以下错误。有什么建议吗?

There should be exactly one item with [DropdownButton]'s value: CategoryDto{ categoryId: cc050c58-876a-4245-9531-be8553c7ae07, name: Masa Oyunları,}. 
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value

'package:flutter/src/material/dropdown.dart':
Failed assertion: line 1584 pos 15: 'items == null || items.isEmpty || value == null ||
              items.where((DropdownMenuItem<T> item) {
                return item.value == value;
              }).length == 1'

下面4个代码片段位于我调用下拉列表的父小部件中(为了方便起见,我只想发布相关部分)。
这是我的父小部件,我在这里调用下拉菜单。(在父小部件中)

state.categories.isNotEmpty
                                ? CategoryDropdown(
                                selectedCategory: _selectedCategory!,
                                handleSelection: selectCategory,
                                labelText: "Category",
                                categories: state.categories)
                                : Container(),

初始化doprdown值为空.(在父窗口小部件中)EventCategory? _selectedCategory;
如果API返回类别列表,则将第一个值设置为_selectedCategory。(在父小部件中)

else if (state is CategoryListSuccess) {
                    _selectedCategory ??= state.categories.first;

selectCategory回调函数。(在父小部件中)

selectCategory(EventCategory eventCategory) {
    setState(() {
      _selectedCategory = eventCategory;
    });
  }

这是我的分类下拉列表。

class CategoryDropdown extends StatelessWidget {
  final String labelText;
  final List<EventCategory> categories;
  final EventCategory selectedCategory;
  final Function handleSelection;

  const CategoryDropdown(
      {Key? key,
      required this.labelText,
      required this.categories,
      required this.selectedCategory,
      required this.handleSelection})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.fromLTRB(6, 0, 0, 0),
          child: Text(
            labelText,
            style: Theme.of(context)
                .textTheme
                .titleMedium
                ?.copyWith(color: Theme.of(context).colorScheme.secondary),
          ),
        ),
        Material(
          elevation: 10,
          borderRadius: BorderRadius.circular(10),
          child: DropdownButtonFormField<EventCategory>(
            value: selectedCategory,
            icon: const Icon(Icons.expand_more),
            elevation: 10,
            onChanged: (EventCategory? category) => handleSelection(category),
            items: categories.map<DropdownMenuItem<EventCategory>>(
                (EventCategory category) {
                  print(selectedCategory);
              return DropdownMenuItem<EventCategory>(
                value: category,
                child: Text(category.name!),
              );
            }).toList(),
          ),
        ),
      ],
    );
  }
}
ljsrvy3e

ljsrvy3e1#

多亏了@pskink,我本来可以解决这个问题的,其实问题不在我的flutter代码,在我的rest API,用Java Sping Boot 写的,我生成了一个虚拟的类别列表API。
下面的代码是错误的。为什么?因为每次我从客户端调用getCategories时(flutter应用),它生成一个新的UUID并发送给客户端。这就是为什么当我第一次使用下拉菜单导航到屏幕时,它会进行API调用并选择第一个返回的元素。然后,当我向后导航时,再次导航到相同的屏幕。我再次从API中获取类别列表。但是,因为我进行了第二次调用,这一次生成并传递了一个新的UUID,这就是为什么第一次调用的UUID与第二次调用的UUID不同。此时DropDown抛出一个Assert错误,因为尽管两个类别的名称相同,但第二个类别的id与第一个类别的id不同,这就是无法实现对象平等的原因。

@GetMapping
    public List<Category> getCategories() throws ResourceNotFoundException {
        List<Category> list = new ArrayList<>();
        list.add(new Category(UUID.randomUUID(),"Category1")); //each call creates a new UUID
        list.add(new Category(UUID.randomUUID(),"Category2"));
        list.add(new Category(UUID.randomUUID(),"Category3"));
        return list;
    }

为了修复这段代码,我将列表设置为静态,并按如下方式传递给客户端。

static  List<Category> categories = fillList();

    @GetMapping
    public List<Category> getCategories() throws ResourceNotFoundException {
        //  throw  new ResourceNotFoundException("Saçamlaamaa");
        return categories;
    }

    private static List<Category> fillList(){
        List<Category> list = new ArrayList<>();

        list.add(new Category(UUID.randomUUID(),"Category1"));
        list.add(new Category(UUID.randomUUID(),"Category2"));
        list.add(new Category(UUID.randomUUID(),"Category3"));
        return list;
    }

相关问题