英文:
Another exception was thrown: ScrollController attached to multiple scroll views Error
问题
我使用PageController
在ChangeNotifier
内作为我的应用程序提供者模型。我想要在另一个屏幕或小部件中更改页面视图,将PageView
索引值更改为此pageController
。此模型运行正常。但是当用户从另一个页面视图(设置)注销时,应用程序将导航到"/"
路由,用户认证后将推送到一个屏幕,该屏幕处理PageView
中的5个页面,如下所示:
return WillPopScope(
onWillPop: () => appTabHandlerProvider.systemPopNavigation(),
child: Scaffold(
body: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: appTabHandlerProvider.pageController,
children: const [
HomeScreen(),
UserTraffic(),
ReserveCategories(),
UserPlates(),
SettingsScreen(),
],
),
bottomNavigationBar: navigationBar,
),
);
但在这个级别,用户无法更改页面视图,并将收到以下错误:
══╡ 异常由手势引发 ╞═════════════════════════════════════════════════════════════════════
处理手势时引发了以下断言:
附加到多个滚动视图的ScrollController。
'package:flutter/src/widgets/scroll_controller.dart':
断言失败:第106行位置12:“_positions.length == 1”。
无论是断言指示了框架本身的错误,还是我们应该在此错误消息中提供更多信息,以帮助您确定和修复根本原因。
在任何情况下,请通过在GitHub上提出错误来报告此断言:
https://github.com/flutter/flutter/issues/new?template=2_bug.md
当抛出异常时,这是堆栈:
#2 ScrollController.position (package:flutter/src/widgets/scroll_controller.dart:106:12)
#3 PageController.jumpToPage (package:flutter/src/widgets/page_view.dart:211:41)
#4 AppTabHandlerProvider.setNewPageControllerIndex= (package:mci_parking/modules/app/provider/app_provider.dart:29:20)
#5 _AppState.build.<anonymous closure> (package:mci_parking/modules/app/screen/app_tab_handler.dart:71:31)
#6 NavigationBar._handleTap.<anonymous closure> (package:flutter/src/material/navigation_bar.dart:207:37)
#7 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1154:21)
#8 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:275:24)
#9 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:654:11)
#10 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:311:5)
#11 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:281:7)
#12 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:167:27)
#13 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:469:20)
#14 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:445:22)
#15 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:331:11)
#16 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:400:7)
#17 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:363:5)
#18 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:320:7)
#19 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:293:9)
#20 _invoke1 (dart:ui/hooks.dart:158:13)
#21 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:382:7)
#22 _dispatchPointerDataPacket (dart:ui/hooks.dart:91:31)
(省略了2个来自_AssertionError类的帧)
Handler:“onTap”
识别器:
TapGestureRecognizer#a5bc4
════════════════════════════════════════════════════════════════════════════════════════════════════
用户可以通过关闭并重新打开应用程序来更改视图,之后`PageController`就可以正常工作。
这是我的AppProvider模型:
```dart
/// # App Tab Handler Provider
///
/// 提供底部导航栏的状态。
class AppTabHandlerProvider with ChangeNotifier {
/// 底部选项卡索引
late int bottomNavigationIndex = 0;
/// 选项卡控制器。将[PageView]和[BottomNavigationBar]连接在一起的工具。
late PageController pageController = PageController();
void initState() {
bottomNavigationIndex = 0;
}
/// 在应用程序退出后释放页面控制器
void get disposePageController {
pageController.dispose();
bottomNavigationIndex = 0;
}
/// 设置新的选项卡索引以更改页面视图
set setNewPageControllerIndex(int index) {
// 更改UI控制器
bottomNavigationIndex = index;
pageController.jumpToPage(index);
notifyListeners();
}
/// # 系统弹出导航
///
/// 将底部导航按钮连接到系统导航弹出按钮。修复
/// SystemPopNavigationButton对BottomNavigationButtons的行为。
systemPopNavigation() {
if (bottomNavigationIndex >= 1 && bottomNavigationIndex <= 4) {
setNewPageControllerIndex = 0;
} else {
// 弹出并退出应用程序
SystemChannels.platform.invokeMethod("SystemNavigator.pop");
}
notifyListeners();
}
}
是的,我知道我们可以将PageController
用作ChangeNotifier
并将其添加到我们的提供者列表中,但在尝试后,我遇到了相同的错误:
另一个异常被抛出:附加到多个滚动视图的ScrollController。
我正在使用Flutter稳定版本3.10.3
和Dart版本3.0.3
。
英文:
I'm using PageController
inside of ChangeNotifier
as my App Provider model. I want to change page view in another screen or widget as module with change PageView
index value to this pageController. This model is working well. But when user logouts from another page view (settings), app will navigate to "/"
route, after user authentication it will push to a screen that handle 5 page inside of PageView
like following:
return WillPopScope(
onWillPop: () => appTabHandlerProvider.systemPopNavigation(),
child: Scaffold(
body: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: appTabHandlerProvider.pageController,
children: const [
HomeScreen(),
UserTraffic(),
ReserveCategories(),
UserPlates(),
SettingsScreen(),
],
),
bottomNavigationBar: navigationBar,
),
);
But at this level user can't change page view and will get following error:
══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
ScrollController attached to multiple scroll views.
'package:flutter/src/widgets/scroll_controller.dart':
Failed assertion: line 106 pos 12: '_positions.length == 1'
Either the assertion indicates an error in the framework itself, or we should provide substantially
more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.md
When the exception was thrown, this was the stack:
#2 ScrollController.position (package:flutter/src/widgets/scroll_controller.dart:106:12)
#3 PageController.jumpToPage (package:flutter/src/widgets/page_view.dart:211:41)
#4 AppTabHandlerProvider.setNewPageControllerIndex= (package:mci_parking/modules/app/provider/app_provider.dart:29:20)
#5 _AppState.build.<anonymous closure> (package:mci_parking/modules/app/screen/app_tab_handler.dart:71:31)
#6 NavigationBar._handleTap.<anonymous closure> (package:flutter/src/material/navigation_bar.dart:207:37)
#7 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1154:21)
#8 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:275:24)
#9 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:654:11)
#10 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:311:5)
#11 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:281:7)
#12 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:167:27)
#13 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:469:20)
#14 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:445:22)
#15 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:331:11)
#16 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:400:7)
#17 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:363:5)
#18 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:320:7)
#19 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:293:9)
#20 _invoke1 (dart:ui/hooks.dart:158:13)
#21 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:382:7)
#22 _dispatchPointerDataPacket (dart:ui/hooks.dart:91:31)
(elided 2 frames from class _AssertionError)
Handler: "onTap"
Recognizer:
TapGestureRecognizer#a5bc4
════════════════════════════════════════════════════════════════════════════════════════════════════
User can change view by close and open application, after that PageController
works well.
Here is my AppProvider model:
/// # App Tab Handler Provider
///
/// Provides state of BottomNavigationBar.
class AppTabHandlerProvider with ChangeNotifier {
/// Bottom tab bar index
late int bottomNavigationIndex = 0;
/// Tab bar controller. A glue between [PageView] and [BottomNavigationBar].
late PageController pageController = PageController();
void initState() {
bottomNavigationIndex = 0;
}
/// Dispose page controller after app exit
void get disposePageController {
pageController.dispose();
bottomNavigationIndex = 0;
}
/// Sets new tab index to change page view
set setNewPageControllerIndex(int index) {
// Changes ui controller
bottomNavigationIndex = index;
pageController.jumpToPage(index);
notifyListeners();
}
/// # System Pop Navigation
///
/// Connects bottom Navigation buttons to system navigation pop button. Fixes
/// behavior of SystemPopNavigationButton to BottomNavigationButtons.
systemPopNavigation() {
if (bottomNavigationIndex >= 1 && bottomNavigationIndex <= 4) {
setNewPageControllerIndex = 0;
} else {
// Pops and exits from App
SystemChannels.platform.invokeMethod("SystemNavigator.pop");
}
notifyListeners();
}
}
Yes I know that we can use PageController
as a ChangeNotifier
and add it to our list of providers, But after try that, I got same error:
Another exception was thrown: ScrollController attached to multiple scroll views.
I'm using Flutter stable version 3.10.3
and dart version 3.0.3
.
答案1
得分: 1
这不是正确的方法。我通过auto_router
策略来修复它,而不是使用PageController。
return AutoTabsRouter(
routes: const [
HomeRoute(),
UserTrafficRoute(),
ReservesRoute(),
PlatesRoute(),
SettingsRoute(),
],
builder: (context, child) {
final tabsRouter = AutoTabsRouter.of(context);
return WillPopScope(
onWillPop: () => appTabHandlerProvider.systemPopNavigation(),
child: Scaffold(
body: child,
bottomNavigationBar: NavigationBar(
height: 80.0,
selectedIndex: appTabHandlerProvider.bottomNavigationIndex,
onDestinationSelected: (int navigationIndex) {
tabsRouter.setActiveIndex(navigationIndex);
appTabHandlerProvider.setNewTabIndex = navigationIndex;
},
destinations: AppNamespace.navigationBarItem
.map(
(NavigationBarChild navigationChildItem) =>
NavigationDestination(
icon: navigationChildItem.selectedIcon,
selectedIcon: navigationChildItem.selectedIcon,
label: t.translate(navigationChildItem.label),
),
)
.toList(),
),
),
);
},
);
英文:
This wasn't proper way. I fixed it by auto_router
strategies instead of PageController.
return AutoTabsRouter(
routes: const [
HomeRoute(),
UserTrafficRoute(),
ReservesRoute(),
PlatesRoute(),
SettingsRoute(),
],
builder: (context, child) {
final tabsRouter = AutoTabsRouter.of(context);
return WillPopScope(
onWillPop: () => appTabHandlerProvider.systemPopNavigation(),
child: Scaffold(
body: child,
bottomNavigationBar: NavigationBar(
height: 80.0,
selectedIndex: appTabHandlerProvider.bottomNavigationIndex,
onDestinationSelected: (int navigationIndex) {
tabsRouter.setActiveIndex(navigationIndex);
appTabHandlerProvider.setNewTabIndex = navigationIndex;
},
destinations: AppNamespace.navigationBarItem
.map(
(NavigationBarChild navigationChildItem) =>
NavigationDestination(
icon: navigationChildItem.selectedIcon,
selectedIcon: navigationChildItem.selectedIcon,
label: t.translate(navigationChildItem.label),
),
)
.toList(),
),
),
);
},
);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论