如何在多个视图中同时使用PrimaryScrollController

Mos*_*e G 5 dart flutter

PrimaryScrollController在自定义有状态小部件中使用 to ,该小部件基本上是一个ListView在用户滚动时从服务器加载项目的代码。我需要PrimaryScrollController,点击 iOS 上的应用栏顶部即可滚动回顶部。

\n\n

我在多个页面中使用相同的小部件,这些小部件由BottomNavigationBar. 我还尝试保持状态,以便当用户滚动,然后更改到底部导航栏中的另一个选项卡,然后返回到第一个选项卡时,滚动位置和从服务器加载的所有项目仍将在那里。

\n\n

为了保留页面的状态,我正在使用IndexedStack. 但是,由于两个页面同时使用,PrimaryScrollController我在控制台中收到一长串相同的错误消息:flutter: Another exception was thrown: ScrollController attached to multiple scroll views.\n我知道这告诉我不应该ScrollController在多个视图中使用相同的错误消息。简单的解决方案是为每个视图创建一个新实例。但是,我必须使用相同的,ScrollController因为我需要PrimaryScrollController点击 iOS 上的应用栏才能工作。

\n\n

如果我只是忽略错误,实际代码就会按照我想要的方式工作,每个页面都会保留自己的状态。\n实际上,它并没有按照我想要的方式工作。当监听器位于单独的页面上时,它们不起作用。

\n\n

我创建了一个示例应用程序来显示问题:

\n\n
import 'package:flutter/material.dart';\nimport 'dart:math';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n  // This widget is the root of your application.\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      title: 'Flutter Demo',\n      theme: ThemeData(\n        primarySwatch: Colors.blue,\n      ),\n      home: MyHomePage(title: 'Flutter Demo Home Page'),\n    );\n  }\n}\n\nclass MyHomePage extends StatefulWidget {\n  MyHomePage({Key key, this.title}) : super(key: key);\n\n  final String title;\n\n  @override\n  _MyHomePageState createState() => _MyHomePageState();\n}\n\nList<Widget> _pages = [\n  BodyWidget(key: PageStorageKey(1)),\n  BodyWidget(key: PageStorageKey(2)),\n];\n\nclass _MyHomePageState extends State<MyHomePage> {\n  int _currentPage = 0;\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(\n        title: Text(widget.title),\n      ),\n      body: IndexedStack(\n        index: _currentPage,\n        children: _pages,\n      ),\n      bottomNavigationBar: BottomNavigationBar(\n          currentIndex: _currentPage,\n          onTap: (int index) {\n            setState(() {\n              _currentPage = index;\n            });\n          },\n          items: [\n            BottomNavigationBarItem(\n                icon: Icon(Icons.star_border), title: Text('page 1')),\n            BottomNavigationBarItem(\n                icon: Icon(Icons.crop_square), title: Text('page 2'))\n          ]),\n    );\n  }\n}\n\nclass BodyWidget extends StatefulWidget {\n  BodyWidget({Key key}) : super(key: key);\n\n  @override\n  _BodyWidgetState createState() => _BodyWidgetState();\n}\n\nclass _BodyWidgetState extends State<BodyWidget> {\n  ScrollController _scrollController;\n  List<int> numbers = [];\n\n  void dataGenerator() {\n    // simulate loading items from server\n    var rng = new Random();\n    for (var i = 0; i < 100; i++) {\n      if (this.mounted) {\n        setState(() {\n          numbers.add(rng.nextInt(100));\n        });\n      }\n    }\n    print('loaded more items');\n  }\n\n  @override\n  void initState() {\n    super.initState();\n\n    // This delay is required to get the build context\n    Future.delayed(\n      Duration.zero,\n      () {\n        _scrollController = PrimaryScrollController.of(context);\n        _scrollController.addListener(() {\n          if (_scrollController.position.pixels >=\n              (_scrollController.position.maxScrollExtent - 50)) {\n            dataGenerator();\n          }\n        });\n        dataGenerator();\n      },\n    );\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ListView.builder(\n      itemCount: numbers.length,\n      controller: _scrollController,\n      itemBuilder: (BuildContext context, int index) {\n        return Container(\n          child: Card(\n            child: Column(\n              children: <Widget>[\n                SizedBox(\n                  height: 15,\n                ),\n                Row(\n                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,\n                  children: <Widget>[\n                    Text('Random number: ' + numbers[index].toString()),\n                    Text('Index: ' + index.toString())\n                  ],\n                ),\n                SizedBox(\n                  height: 15,\n                ),\n              ],\n            ),\n          ),\n        );\n      },\n    );\n  }\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是抛出的错误:

\n\n
flutter: \xe2\x95\x90\xe2\x95\x90\xe2\x95\xa1 EXCEPTION CAUGHT BY FOUNDATION LIBRARY \xe2\x95\x9e\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nflutter: The following assertion was thrown while dispatching notifications for ScrollController:\nflutter: ScrollController attached to multiple scroll views.\nflutter: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 111 pos 12:\nflutter: '_positions.length == 1'\nflutter:\nflutter: Either the assertion indicates an error in the framework itself, or we should provide substantially\nflutter: more information in this error message to help you determine and fix the underlying cause.\nflutter: In either case, please report this assertion by filing a bug on GitHub:\nflutter:   https://github.com/flutter/flutter/issues/new?template=BUG.md\nflutter:\nflutter: When the exception was thrown, this was the stack:\nflutter: #2      ScrollController.position \npackage:flutter/\xe2\x80\xa6/widgets/scroll_controller.dart:111\nflutter: #3      _BodyWidgetState.initState.<anonymous closure>.<anonymous closure>\npackage:primaryscrollcontroller_test/main.dart:97\nflutter: #4      ChangeNotifier.notifyListeners \npackage:flutter/\xe2\x80\xa6/foundation/change_notifier.dart:206\nflutter: #5      ChangeNotifier.notifyListeners \npackage:flutter/\xe2\x80\xa6/foundation/change_notifier.dart:206\nflutter: #6      ScrollPosition.notifyListeners \npackage:flutter/\xe2\x80\xa6/widgets/scroll_position.dart:696\nflutter: #7      ScrollPosition.setPixels \npackage:flutter/\xe2\x80\xa6/widgets/scroll_position.dart:218\nflutter: #8      ScrollPositionWithSingleContext.setPixels \npackage:flutter/\xe2\x80\xa6/widgets/scroll_position_with_single_context.dart:84\nflutter: #9      ScrollPositionWithSingleContext.applyUserOffset \npackage:flutter/\xe2\x80\xa6/widgets/scroll_position_with_single_context.dart:127\nflutter: #10     ScrollDragController.update \npackage:flutter/\xe2\x80\xa6/widgets/scroll_activity.dart:372\nflutter: #11     ScrollableState._handleDragUpdate \npackage:flutter/\xe2\x80\xa6/widgets/scrollable.dart:496\nflutter: #12     DragGestureRecognizer.handleEvent.<anonymous closure> \nflutter: #13     GestureRecognizer.invokeCallback \npackage:flutter/\xe2\x80\xa6/gestures/recognizer.dart:166\nflutter: #14     DragGestureRecognizer.handleEvent \npackage:flutter/\xe2\x80\xa6/gestures/monodrag.dart:182\nflutter: #15     PointerRouter._dispatch \npackage:flutter/\xe2\x80\xa6/gestures/pointer_router.dart:73\nflutter: #16     PointerRouter.route \npackage:flutter/\xe2\x80\xa6/gestures/pointer_router.dart:101\nflutter: #17     _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent \npackage:flutter/\xe2\x80\xa6/gestures/binding.dart:221\nflutter: #18     _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent \npackage:flutter/\xe2\x80\xa6/gestures/binding.dart:199\nflutter: #19     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent \npackage:flutter/\xe2\x80\xa6/gestures/binding.dart:156\nflutter: #20     _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue \npackage:flutter/\xe2\x80\xa6/gestures/binding.dart:102\nflutter: #21     _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket \npackage:flutter/\xe2\x80\xa6/gestures/binding.dart:86\nflutter: #25     _invoke1  (dart:ui/hooks.dart:233:10)\nflutter: #26     _dispatchPointerDataPacket  (dart:ui/hooks.dart:154:5)\nflutter: (elided 5 frames from class _AssertionError and package dart:async)\nflutter:\nflutter: The ScrollController sending notification was:\nflutter:   ScrollController#be798(2 clients)\nflutter: \xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nflutter: Another exception was thrown: ScrollController attached to multiple scroll views.\nflutter: Another exception was thrown: ScrollController attached to multiple scroll views.\nflutter: Another exception was thrown: ScrollController attached to multiple scroll views.\nflutter: Another exception was thrown: ScrollController attached to multiple scroll views.\n
Run Code Online (Sandbox Code Playgroud)\n\n

线路flutter: Another exception was thrown: ScrollController attached to multiple scroll views.不断重复很多次

\n\n

我该如何解决这个问题?

\n

yag*_*ete 0

老了,那里有很多答案。几个月前,我遇到了类似的问题:

\n

正如问题所述,您有多个位置(多个可滚动视图)。

\n

像往常一样声明:

\n
ScrollController scrollController;\n
Run Code Online (Sandbox Code Playgroud)\n

//注意,位置,包含有关滚动偏移、物理等的信息\xc3\xb3n,这个“位置”是一个可迭代的。,你可能会猜到,这里是所有的位置 scrolls "position" are stored (one for each scrollable view attached for this @scrollController" .

\n
final scrollPositions = scrollController.positions;\n
Run Code Online (Sandbox Code Playgroud)\n

//给定我获取最新一个的位置长度,在我的用例中它始终是最后一个(来回执行新列表),您可以根据您的需要对其进行调整以获取位置信息。

\n
final scrollPositionImInterested = scrollPositions\n        .elementAt(scrollController.positions.length - 1);\n
Run Code Online (Sandbox Code Playgroud)\n

希望这可以帮助有相同需求的人

\n