使用ScopedModel筛选Flutter ListView会引发奇怪的错误

时间:2018-07-17 20:56:55

标签: dart flutter flutter-layout

我有一个应用程序,其中显示字符串列表,用户可以在其中键入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);

}

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

Error output

这是堆栈跟踪:

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.

1 个答案:

答案 0 :(得分:1)

您缺少一件很小的东西。 ListView.builder取值itemCount来说明列表的长度,而您没有提到itemCount的{​​{1}}的值,因此编译器会继续一次又一次地编译itemBuilder函数直到错误超出范围为止。也就是说,如果您的列表(已过滤)的长度为2,则当函数以索引值2(即列表ListView.builder的第三个元素)运行时,就会出现错误 不存在,因为过滤列表的长度为2 您需要做的是: 将此属性添加到您的filtered[2]

ListView.builder