I have a child widget, with three Text() subwidgets that each need a scroll controller. Some of the Text() subwidgets may not exceed the width of their parent, but for those that do I would like them to scroll so that the user can see the full string.
This child widget is built using a listview.builder. I do not attach a controller using the listview.builder controller named argument - as I need to have one controller per text widget in each child as ScrollControllers are not multi-use. I use timers to trigger the scrolling behaviour and also to return the text to its start position.
Im having sporadic errors in flutter when I scroll, because the ScrollControllers dont appear to be being attached correctly. I dont want to just catch-and-ignore, id like to see what error im making in specification of the scroll controllers.
Visually, when a scroll down the listview I can still see the scrolling behaviour, I just get a stream of errors like this:
E/flutter (32685): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 199 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.
E/flutter (32685): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:51:61)
E/flutter (32685): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:40:5)
E/flutter (32685): #2 ScrollController.animateTo (package:flutter/src/widgets/scroll_controller.dart:199:12)
E/flutter (32685): #3 _TenderTileState._scrollText.<anonymous closure>.<anonymous closure> (package:WiseBuy/UI/tiles/tender_tile.dart:119:28)
E/flutter (32685): #4 new Future.delayed.<anonymous closure> (dart:async/future.dart:427:39)
E/flutter (32685): #5 Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
E/flutter (32685): #6 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:398:19)
E/flutter (32685): #7 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5)
E/flutter (32685): #8 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)
E/flutter (32685):
Scroll Controller Instantiation
class Tile extends ConsumerStatefulWidget {
final ScrollController scrollControllerSummary = ScrollController();
final ScrollController scrollControllerNote = ScrollController();
final ScrollController scrollControllerInsight = ScrollController();
// other Tile variables
}
Each Tile Widgets init(), dispose() and timer trigger
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
// define the auto-scroll timers for auto-scrolling views!
_scrollTimer = Timer.periodic(const Duration(seconds: 2), (timer) {
_scrollText(widget.scrollControllerSummary);
_scrollText(widget.scrollControllerNote);
_scrollText(widget.scrollControllerInsight);
});
});
}
@override
void dispose() {
_scrollTimer?.cancel();
widget.scrollControllerSummary.dispose();
widget.scrollControllerNote.dispose();
widget.scrollControllerInsight.dispose();
super.dispose();
}
void _scrollText(ScrollController scrollController) async {
if (scrollController.hasClients) {
await scrollController.animateTo(
scrollController.position.maxScrollExtent,
duration: const Duration(seconds: 3),
curve: Curves.ease,
).then((_) {
// Delay before resetting the scroll position
Future.delayed(const Duration(seconds: 1), () {
scrollController.animateTo(
0.0,
duration: const Duration(seconds: 1),
curve: Curves.ease,
);
});
});
}
}
Each Text() widget has its own scroll controller like this:
SingleChildScrollView(
controller: widget.scrollControllerSummary,
scrollDirection: Axis.horizontal,
child: Text(
softWrap: false,
'Text here!',
),
)