Well, I think you are in the correct track to achieve it!
You should try _controller.jumpTo() and fire that event programatically.
You can create a Timer, and call the _controller in there, after 500 milliseconds (half of a second).
ScrollController _myController = ScrollController();
@override
Widget build(BuildContext context) {
// here we set the timer to call the event
Timer(Duration(milliseconds: 500), () => _myController.jumpTo(_myController.position.maxScrollExtent));
// add _myController to the ListView
return ListView.builder(
controller: _myController,
// itemCount: yourItemsCount,
// ...
)
}
Please check this answer also -->
Programmatically scrolling to the end of a ListView
And also this one --> How to get full size of a ScrollController
There they use SchedulerBinding.instance.addPostFrameCallback which I think is also a good solution to fire your scroll.
SchedulerBinding.instance.addPostFrameCallback((_) {
_myController.animateTo(
_myController.position.maxScrollExtent,
duration: const Duration(milliseconds: 500),
curve: Curves.easeOut,
);
});
UPDATE:
Please try this code, no transition, no visible jump to me.
Is a combination of my previous paragraphs.
Just beware, if the number of lines grow, like 10000.
But I think you should control the number of messages displayed.
Widget build(BuildContext context) {
final items = List<String>.generate(50, (i) => "Item $i");
ScrollController _controller = ScrollController();
SchedulerBinding.instance.addPostFrameCallback((_) {
_controller.jumpTo(_controller.position.maxScrollExtent);
});
return Scaffold(
body: SafeArea(
child: ListView.builder(
controller: _controller,
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${items[index]}'),
);
},
),
));
}