Reputation: 81
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).
Upvotes: 8
Views: 9154
Reputation: 438
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);
}
Upvotes: 1
Reputation: 4413
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(),
)
Upvotes: 3
Reputation: 126624
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.
Upvotes: 4