代码之家  ›  专栏  ›  技术社区  ›  kmort

启用enableFilter后,Flutter DropdownMenu会超出界限

  •  1
  • kmort  · 技术社区  · 5 月前

    太长,读不下去了 打开过滤后,我的下拉菜单中出现了越界错误,我不知道为什么。

    我正在学习Flutter。我的下拉菜单崩溃了 RangeError Index out of range 如果我选择了下拉菜单中的第一个条目之外的任何内容,并且 enableFilter: true, 已设置。它不会这样做 enableFilter: false .

    我尝试过的事情:

    有人能帮我理解一下吗:

    • 发生了什么,是否与上述StackOverflow问题有关

    --或--

    • 我做错了什么?
    import 'dart:developer';
    import 'package:flutter/material.dart';
    
    class PageFive extends StatefulWidget
    {
      const PageFive({super.key});
      
      @override
      State<StatefulWidget> createState()
      {
        return PageFiveState();
      } 
    }
    
    enum Villian { Gargamil, Doofenschmirtz, Kinderlumper }
    enum LevelOfBadness {I, II, III, IV, V, X}
    
    class PageFiveState extends State
    {
      Villian? theBiggestVillian;
      LevelOfBadness? selectedBadnessRating;
      TextEditingController tfc = TextEditingController();
    
    @override
      Widget build(BuildContext context)
      {
        return MaterialApp(
          home: SafeArea(
            child: Scaffold(
              backgroundColor: Colors.amber[200] ,
              appBar: AppBar(
                centerTitle: true,
                title: const Text("This is light red"),
                backgroundColor: Colors.red[300]),
              body:
               Container(
                    margin: const EdgeInsets.all(15.0),
                    padding: const EdgeInsets.all(3.0),
                    decoration: BoxDecoration(border: Border.all(color: Colors.blueAccent)),
               child: Row (
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  Flexible(
                    child: Container(
                      margin: const EdgeInsets.all(15.0),
                      padding: const EdgeInsets.all(3.0),
                      decoration: BoxDecoration(border: Border.all(color: Colors.redAccent)),
                      child: SizedBox(
                        child: Column(
                          children: [
                            const Text("Choose a Villian"),
                            RadioListTile<Villian> (
                              tileColor: Colors.blue,
                              title: Text(Villian.Gargamil.name),
                              groupValue: theBiggestVillian,
                              value: Villian.Gargamil,
                              onChanged: (Villian? newValue) {
                                setState(() {
                                theBiggestVillian = newValue;
                              });
                              },
                            ),
                            RadioListTile<Villian> (
                              tileColor: Colors.green,
                              title: Text(Villian.Doofenschmirtz.name),
                              groupValue: theBiggestVillian,
                              value: Villian.Doofenschmirtz,
                              onChanged: (Villian? newValue) {
                                setState(() {
                                theBiggestVillian = newValue;
                              });
                              },
                            ),
                            RadioListTile<Villian> (
                              tileColor: Colors.orange,
                              title: Text(Villian.Kinderlumper.name),
                              groupValue: theBiggestVillian,
                              value: Villian.Kinderlumper,
                              onChanged: (Villian? newValue) {
                                setState(() {
                                theBiggestVillian = newValue;
                                log(theBiggestVillian.toString());
                              });
                              },
                            ),
    
                            const Spacer(),
                            const Text("Select a Badness Rating"),
                            DropdownMenu(
                              // enableFilter: true, // If I turn this on, I get out of bounds exceptions whenever I select anything but the first entry. Why?
                              onSelected: (currentBadnessSelectedInDropdownMenu) {
                                if (currentBadnessSelectedInDropdownMenu !=null)
                                {
                                  setState(() 
                                  {
                                    log("Type is: " + currentBadnessSelectedInDropdownMenu.runtimeType.toString());
                                    log("Value is: " + currentBadnessSelectedInDropdownMenu.toString());
                                    selectedBadnessRating = currentBadnessSelectedInDropdownMenu;
                                  });
                                }
                              },
                              dropdownMenuEntries: const <DropdownMenuEntry<LevelOfBadness>>[
                              DropdownMenuEntry(value: LevelOfBadness.I, label: "Underwhelming"),
                              DropdownMenuEntry(value: LevelOfBadness.II, label: "Rookie"),
                              DropdownMenuEntry(value: LevelOfBadness.III, label: "Moderate"),
                              DropdownMenuEntry(value: LevelOfBadness.IV, label: "Fully-Operational"),
                              DropdownMenuEntry(value: LevelOfBadness.V, label: "Level 5 Baddie"),
                              DropdownMenuEntry(value: LevelOfBadness.X, label: "Mega-baddie!"),
                            ],
                          ),
    
                            const Spacer(),
                            const Text("Type a Characteristic"),
                              TextField(
                                controller: tfc,
                                onChanged: textFieldChangedCallback,
                                decoration: const InputDecoration(
                                  border: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(12))),
                                  hintText: 'Write something here',
                                ),
                              ),
                            const Spacer(),
                            ],
                          ),
                      ),
                    ),
                  ),
                  Container(
                    margin: const EdgeInsets.all(15.0),
                    padding: const EdgeInsets.all(3.0),
                    decoration: BoxDecoration(border: Border.all(color: Colors.greenAccent)),
                    child: SizedBox(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            const Spacer(),
                            const Padding(padding: EdgeInsets.all(10)),
                            SizedBox(
                              width: 150,
                              child: Text("Our villian, ${theBiggestVillian?.name??""}, is of calibre $selectedBadnessRating. Most folks would describe them as ${tfc.value.text}. In conclusion, don't be a villian."),
                              ),
                            const Spacer(),
                            Row( 
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                ElevatedButton(onPressed: onPressedSubmit, child: const Text("Submit")),
                                // Spacer(), // if I put a Spacer() here, I get unbounded size! Grr.
                                ElevatedButton(onPressed: onPressedReset, child: const Text("Reset")),
                              ],
                            ),
                            const Spacer(),
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    
    void onPressedSubmit()
    {
    setState(() {
        // todo
      });
    }
    
    void onPressedReset()
    {
      setState(() {
        tfc.text = "";
        theBiggestVillian = null;
        // selectedBadnessRating = null; // This doesn't do what I want yet either. I want to be able to deselect the item....
        log("Reset ran");
      });
    }
    
    void textFieldChangedCallback(String newValue)
    {
      setState(() {});
    }
    
    }
    
    
    
    1 回复  |  直到 5 月前
        1
  •  1
  •   Md. Yeasin Sheikh    5 月前

    你需要提供 filtercallback 什么时候 enabledFilter:true

    child: DropdownMenu<LevelOfBadness>(
      enableFilter: true,
      filterCallback: (entries, filter) {
        return entries;
      },