使用 ScopedModel 过滤 Flutter ListView 会抛出奇怪的错误

Using ScopedModel to filter a Flutter ListView throws strange error

我有一个应用程序,我在其中显示了一个字符串列表,用户可以在其中键入 TextField 来过滤列表项。我正在使用 ScopedModel 更新我将根据用户在父窗口小部件中键入的内容应用于列表的过滤器。

我的 ScopedModel 工作完全正常,每输入一个新字母我都会收到更新。

我遇到的问题是,当我更新列表时,当我只输入一两个字符时过滤成功。如果我输入三个或更多,我会收到一个错误,我不确定我能否正确破译。我已经用 20 个项目的列表和 2000 个项目的列表尝试了这个,结果在每种情况下都是相同的。

知道我做错了什么吗?

class MyListView extends StatefulWidget {
  final String id;
  final List<Content> items;

  MyListView(this.id, this.items);

  @override
  State<StatefulWidget> createState() => _MyListViewState(id, items);
}

class _MyListViewState extends State<MyListView> {
  final String id;
  List<Content> items;

  _MyListViewState(this.id, this.items);

  @override
  Widget build(BuildContext context) {
    return ScopedModelDescendant<ContentListDisplayOptions>(
      builder: (context, child, model) {
        List<Content> filtered = filter(model, items);
        if(filtered == null || filtered.isEmpty) {
          return Column(children: <Widget>[Text("empty")]);
        } else {
          return ListView.builder(
              itemBuilder: (BuildContext context, int index) {
                return ListTile(
                  title: Text(filtered[index].name),
                );
              });
        }
      },
    );
  }

  List<Content> filter(
      ContentListDisplayOptions model, List<Content> names) {
    if (noSearchFilters(model)) {
      return names;
    }

    return names
        .where((i) => i.name.startsWith(model.filter.searchQuery))
        .toList();
  }

  bool noSearchFilters(ContentListDisplayOptions model) =>
      model == null || model.filter == null || model.filter.searchQuery == null;
}

ContentListDisplayOptions

class ContentListDisplayOptions extends Model {

  Filter _filter;

  Filter get filter => _filter;

  void updateFilters(Filter filter) {
    this._filter = filter;
    notifyListeners();
  }
}

class Filter {

  final String searchQuery;

  Filter(this.searchQuery);

}

错误也以一种奇怪的方式表现出来。它并不总是占据整个屏幕:

这是堆栈跟踪:

flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following RangeError was thrown building MediaQuery(MediaQueryData(size: Size(375.0, 812.0),
flutter: devicePixelRatio: 3.0, textScaleFactor: 1.0, padding: EdgeInsets.zero, viewInsets: EdgeInsets.zero,
flutter: alwaysUse24HourFormat: false)):
flutter: RangeError (index): Invalid value: Only valid value is 0: 1
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0      List.[] (dart:core/runtime/libgrowable_array.dart:141:60)
flutter: #1      _MyListViewState.build.<anonymous closure>.<anonymous closure> (package:my_app/names/names_list.dart:33:39)
flutter: #2      SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:197:20)
flutter: #3      SliverMultiBoxAdaptorElement._build.<anonymous closure> (package:flutter/src/widgets/sliver.dart:716:67)
flutter: #4      _HashMap.putIfAbsent (dart:collection/runtime/libcollection_patch.dart:143:29)
flutter: #5      SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:716:26)
flutter: #6      SliverMultiBoxAdaptorElement.performRebuild (package:flutter/src/widgets/sliver.dart:702:69)
flutter: #7      SliverMultiBoxAdaptorElement.update (package:flutter/src/widgets/sliver.dart:671:7)
flutter: #8      Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #9      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
flutter: #10     Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
flutter: #11     ProxyElement.update (package:flutter/src/widgets/framework.dart:3909:5)
flutter: #12     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #13     SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
flutter: #14     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #15     RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:4379:32)
flutter: #16     MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4769:17)
flutter: #17     _ViewportElement.update (package:flutter/src/widgets/viewport.dart:192:11)
flutter: #18     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #19     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
flutter: #20     Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
flutter: #21     ProxyElement.update (package:flutter/src/widgets/framework.dart:3909:5)
flutter: #22     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #23     SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
flutter: #24     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #25     SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
flutter: #26     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #27     SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
flutter: #28     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #29     SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
flutter: #30     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #31     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
flutter: #32     Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
flutter: #33     StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
flutter: #34     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #35     SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4661:14)
flutter: #36     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #37     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
flutter: #38     Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
flutter: #39     StatefulElement.update (package:flutter/src/widgets/framework.dart:3799:5)
flutter: #40     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #41     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
flutter: #42     Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
flutter: #43     ProxyElement.update (package:flutter/src/widgets/framework.dart:3909:5)
flutter: #44     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #45     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
flutter: #46     Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
flutter: #47     StatelessElement.update (package:flutter/src/widgets/framework.dart:3702:5)
flutter: #48     Element.updateChild (package:flutter/src/widgets/framework.dart:2699:15)
flutter: #49     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3653:16)
flutter: #50     Element.rebuild (package:flutter/src/widgets/framework.dart:3495:5)
flutter: #51     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2242:33)
flutter: #52     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:626:20)
flutter: #53     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:208:5)
flutter: #54     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
flutter: #55     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
flutter: #56     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
flutter: #57     _invoke (dart:ui/hooks.dart:120:13)
flutter: #58     _drawFrame (dart:ui/hooks.dart:109:3)
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
flutter: Another exception was thrown: A RenderSliverPadding expected a child of type RenderSliver but received a child of type RenderErrorBox.
flutter: Another exception was thrown: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 3497 pos 14: 'owner._debugCurrentBuildTarget == this': is not true.
flutter: Another exception was thrown: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 3497 pos 14: 'owner._debugCurrentBuildTarget == this': is not true.
flutter: Another exception was thrown: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 3497 pos 14: 'owner._debugCurrentBuildTarget == this': is not true.
flutter: Another exception was thrown: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 3497 pos 14: 'owner._debugCurrentBuildTarget == this': is not true.
flutter: Another exception was thrown: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 3497 pos 14: 'owner._debugCurrentBuildTarget == this': is not true.
flutter: Another exception was thrown: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 3497 pos 14: 'owner._debugCurrentBuildTarget == this': is not true.

你漏掉了一个很小的东西。 ListView.builder 取一个值 itemCount 来告诉列表的长度,而您没有提到 ListView.builderitemCount 的值,因此编译器会一次又一次地编译 itemBuilder 函数直到它给出超出范围的错误。即,如果您的列表(已过滤)的长度为 2,则当函数以索引值 2 运行时会出现错误,即列表的第 3 个元素 filtered[2] 不存在,因为过滤列表的长度为 2 你需要做的是:- 将此 属性 添加到您的 ListView.builder

itemCount : filtered.length,