When adding new items (e.g. a ListTile) to a ListView is there a way to scroll the newly added item into view? The new item may not be at the bottom of the list (e.g. it is sorted alphabetically).
-
is there a way to scroll the newly added item into view? -> do you mean you want the screen to auto scroll to the newly added item? – Arnold Parge Nov 20 '17 at 12:20
-
Does this answer your question? [Flutter: Scrolling to a widget in ListView](https://stackoverflow.com/questions/49153087/flutter-scrolling-to-a-widget-in-listview) – TWL Nov 18 '19 at 23:12
3 Answers
You can scroll through a ListView
using a ScrollController
.
final scrollController = ScrollController();
// ...
ListView(controller: scrollController // ...
);
// ...
scrollController.animateTo(height, duration: Duration(milliseconds: 678),
curve: Curves.ease);
You will have to determine the height yourself. That could be done using the index of your item and the general item height.
There is a full example available here.

- 114,516
- 58
- 291
- 402
-
1This solution does not work for me because my app has different types of contents (text, photos, videos, contacts, locations) and their height does vary (not same) in ListView. Thanks for your suggestion. – Kamlesh Mar 20 '21 at 05:45
You can use the following library from quire-io team to scroll ListView to the position:
https://github.com/quire-io/scroll-to-index
ListView(
scrollDirection: scrollDirection,
controller: controller,
children: randomList.map<Widget>((data) {
final index = data[0];
final height = data[1];
return AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
child: Text('index: $index, height: $height'),
highlightColor: Colors.black.withOpacity(0.1),
);
}).toList(),
)

- 4,195
- 2
- 42
- 53
Expanding on @creativecreatorormaybenot, if you want to do this after you have added an item, of course you need to prompt it to draw with a setstate, but there are some other critical pieces. For example, this code will automatically scroll so that the end of the list is visible just after it builds the list:
class MyList extends StatefulWidget {
@override
_MyState createState() => _MyState();
}
class _MyState extends State<MyList> {
ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
}
void _onAfterBuild(BuildContext context) {
_scrollController.animateTo(double.maxFinite, /* <- the offset in units to scroll to */
duration: Duration(milliseconds: 1), curve: Curves.ease);
}
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) => _onAfterBuild(context));
return ListView.builder(
controller: _scrollController,
//initialScrollIndex: appState.doseEvents?.length ?? 0,
itemCount: 20,
itemBuilder: (BuildContext ctxt, int index) {
return Row(
children: <Widget>[
Text("A"),
Text("B"),
Text("C"),
],
);
});
}
}
If you want to go to a particular item, you are going to have to compute the offset to that item in _onAfterBuild. For example:
void _onAfterBuild(BuildContext context) {
double scrollPos = _mostRecentlyAddedIndex * _itemHeight;
_scrollController.animateTo(scrollPos,
duration: Duration(milliseconds: 1), curve: Curves.ease);
}

- 408
- 5
- 10