-
Notifications
You must be signed in to change notification settings - Fork 27.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Flutter 2.5.0] Nested Scrollables in PageView produces error logs but app works normally #89864
Comments
Same problem here: "The provided ScrollController is currently attached to more than one ScrollPosition." |
Hi @iandis, please provide a minimal complete reproducible code sample? Thank you |
@danagbemava-nc Sure. Codeimport 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final PageController _pageController = PageController();
final ValueNotifier<int> _bottomNavNotifier = ValueNotifier<int>(0);
void _onPageChanged(int index) {
_bottomNavNotifier.value = index;
}
void _movePageTo(int index) {
_pageController.animateToPage(
index,
duration: const Duration(milliseconds: 500),
curve: Curves.fastLinearToSlowEaseIn,
);
}
Widget _listItemsBuilder(BuildContext context, int index) {
return const Padding(
padding: EdgeInsets.only(bottom: 40, right: 10),
child: SizedBox(
width: 200,
child: ColoredBox(
color: Colors.grey,
child: Center(
child: Text('X Item'),
),
),
),
);
}
Widget get _sliver {
return SliverToBoxAdapter(
child: SizedBox(
height: 450,
child: ListView.builder(
padding: const EdgeInsets.all(20),
scrollDirection: Axis.horizontal,
itemBuilder: _listItemsBuilder,
itemCount: 20,
),
),
);
}
List<Widget> get _pages {
return [
CustomScrollView(slivers: List<Widget>.filled(3, _sliver)),
CustomScrollView(slivers: List<Widget>.filled(3, _sliver)),
];
}
List<BottomNavigationBarItem> get _bottomNavBarItems {
return const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
];
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _pageController,
onPageChanged: _onPageChanged,
children: _pages,
),
bottomNavigationBar: ValueListenableBuilder<int>(
valueListenable: _bottomNavNotifier,
builder: (_, int currentIndex, __) {
return BottomNavigationBar(
items: _bottomNavBarItems,
currentIndex: currentIndex,
onTap: _movePageTo,
);
},
),
);
}
} If the error logs do not appear, try quickly move to the next or previous page after scrolling vertically |
@iandis, do you use the |
@danagbemava-nc it was scroll-wheel scrolling, running on desktop mode web, not the mobile mode one. |
Hi @iandis, thanks for filing the issue. I could not reproduce it with Tested on The error message does however provide a clear way to solve the issue. Regardless, I will label it for visibility. updated code sampleimport 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods and getters like dragDevices
@override
Set<PointerDeviceKind> get dragDevices => {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
// etc.
};
}
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
scrollBehavior: MyCustomScrollBehavior(),
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final PageController _pageController = PageController();
final ValueNotifier<int> _bottomNavNotifier = ValueNotifier<int>(0);
void _onPageChanged(int index) {
_bottomNavNotifier.value = index;
}
void _movePageTo(int index) {
_pageController.animateToPage(index,
duration: const Duration(milliseconds: 500), curve: Curves.easeIn);
}
Widget _listItemsBuilder(BuildContext context, int index) {
return const Padding(
padding: EdgeInsets.only(bottom: 40, right: 10),
child: SizedBox(
width: 200,
child: ColoredBox(
color: Colors.grey,
child: Center(
child: Text('X Item'),
),
),
),
);
}
Widget get _sliver {
return SliverToBoxAdapter(
child: SizedBox(
height: 450,
child: ListView.builder(
padding: const EdgeInsets.all(20),
scrollDirection: Axis.horizontal,
itemBuilder: _listItemsBuilder,
itemCount: 20,
),
),
);
}
List<Widget> get _pages {
return [
CustomScrollView(slivers: List<Widget>.filled(3, _sliver)),
CustomScrollView(slivers: List<Widget>.filled(3, _sliver)),
];
}
List<BottomNavigationBarItem> get _bottomNavBarItems {
return const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
];
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _pageController,
onPageChanged: _onPageChanged,
children: _pages,
),
bottomNavigationBar: ValueListenableBuilder<int>(
valueListenable: _bottomNavNotifier,
builder: (_, int currentIndex, __) {
return BottomNavigationBar(
items: _bottomNavBarItems,
currentIndex: currentIndex,
onTap: _movePageTo,
);
},
),
);
}
}
logsLaunching lib/main.dart on Chrome in debug mode...
This app is linked to the debug service: ws://127.0.0.1:63411/LLNdAdxZdZA%3D/ws
Debug service listening on ws://127.0.0.1:63411/LLNdAdxZdZA=/ws
💪 Running with sound null safety 💪
Connecting to VM Service at ws://127.0.0.1:63411/LLNdAdxZdZA=/ws
════════ Exception caught by animation library ═════════════════════════════════
The following assertion was thrown while notifying status listeners for AnimationController:
The provided ScrollController is currently attached to more than one ScrollPosition.
The Scrollbar requires a single ScrollPosition in order to be painted.
When the scrollbar is interactive, the associated Scrollable widgets must have unique ScrollControllers. The provided ScrollController must be unique to a Scrollable widget.
When the exception was thrown, this was the stack
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49 throw_
packages/flutter/src/widgets/scrollbar.dart 1283:9 <fn>
packages/flutter/src/widgets/scrollbar.dart 1306:14 [_debugCheckHasValidScrollPosition]
packages/flutter/src/widgets/scrollbar.dart 1225:14 [_validateInteractions]
packages/flutter/src/animation/listener_helpers.dart 233:27 notifyStatusListeners
packages/flutter/src/animation/animation_controller.dart 816:7 [_checkStatusChanged]
packages/flutter/src/animation/animation_controller.dart 750:5 [_startSimulation]
packages/flutter/src/animation/animation_controller.dart 613:12 [_animateToInternal]
packages/flutter/src/animation/animation_controller.dart 495:12 reverse
packages/flutter/src/widgets/scrollbar.dart 1382:37 <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19 internalCallback
The AnimationController notifying status listeners was: AnimationController#2346a(◀ 1.000)
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by animation library ═════════════════════════════════
The provided ScrollController is currently attached to more than one ScrollPosition.
════════════════════════════════════════════════════════════════════════════════
flutter doctor -v[✓] Flutter (Channel stable, 2.5.0, on macOS 11.5.1 20G80 darwin-arm, locale en-GB)
• Flutter version 2.5.0 at /Users/nexus/dev/sdks/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 4cc385b4b8 (7 days ago), 2021-09-07 23:01:49 -0700
• Engine revision f0826da7ef
• Dart version 2.14.0
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
• Android SDK at /Users/nexus/Library/Android/sdk
• Platform android-31, build-tools 31.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 12.5.1, Build version 12E507
• CocoaPods version 1.11.0
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2020.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
[✓] VS Code (version 1.60.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.26.0
[✓] Connected device (4 available)
• M2007J20CG (mobile) • 5dd3be00 • android-arm64 • Android 11 (API 30)
• iPhone 12 (mobile) • F2592D43-5FE3-46BB-8A2B-A38BA468DCE9 • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 11.5.1 20G80 darwin-arm
• Chrome (web) • chrome • web-javascript • Google Chrome 93.0.4577.63
• No issues found! [✓] Flutter (Channel master, 2.6.0-6.0.pre.94, on macOS 11.5.1 20G80 darwin-arm, locale en-GB)
• Flutter version 2.6.0-6.0.pre.94 at /Users/nexus/dev/sdks/flutters
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision ec61450030 (8 hours ago), 2021-09-14 19:12:05 -0400
• Engine revision abb1980f65
• Dart version 2.15.0 (build 2.15.0-96.0.dev)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
• Android SDK at /Users/nexus/Library/Android/sdk
• Platform android-31, build-tools 31.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 12.5.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• CocoaPods version 1.11.0
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2020.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
[✓] VS Code (version 1.60.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.26.0
[✓] Connected device (4 available)
• M2007J20CG (mobile) • 5dd3be00 • android-arm64 • Android 11 (API 30)
• iPhone 12 (mobile) • F2592D43-5FE3-46BB-8A2B-A38BA468DCE9 • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 11.5.1 20G80 darwin-arm
• Chrome (web) • chrome • web-javascript • Google Chrome 93.0.4577.63
• No issues found! |
/cc @Piinks |
Hi there! It looks like you are having scrollbar issues on desktop (+ web running on desktop). This is because Scrollbars are automatically applied to ScrollViews on desktop platforms by the ScrollBehavior. I believe this is expected behavior. Providing a unique ScrollController to one or both of your ScrollViews should resolve your issue, or you can configure your ScrollBehavior as you like using the information in this guide. |
Hi thank you for the clarification. I think it's clear now that when I provide ScrollControllers to the ScrollViews, this error log does not appear. But I think instead of throwing error from the Animation Library, it would be better to throw it from the ScrollView instead so people would not be confused of the error message and would be able to resolve it. |
Great! I am glad that resolved your issue. I think it is coming from the animation library because the OP is executing an animation on the ScrollView. _pageController.animateToPage(
index,
duration: const Duration(milliseconds: 500),
curve: Curves.fastLinearToSlowEaseIn,
); In that case the error message is accurate, and provides an explanation of what the issue is and how to resolve it. If there is something else we can add to the error message, please let us know. :) |
I agree with you about the error message being accurate, however the stacktrace doesn't look helpful to users since it points at the Animation Library and not the problematic ScrollView. Other than that I think is okay. |
@Piinks We now do know the error is from auto implemented scrollbar on desktop. So we need to assign a I am still insist on that, the default behavior of Maybe, can flutter provide such a solution, optionally change the default controller from Disable auto implementation of scrollbar is not a solution, just escape from the problem. |
The |
Steps to Reproduce
PageView
that's structured like thisPageView
Expected results:
No error logs
Actual results:
Exception thrown by the animation library
Logs
flutter run -d chrome
flutter analyze
flutter doctor -v
Notes:
ScrollController
to each of theCustomScrollView
sThe text was updated successfully, but these errors were encountered: