- Published on
How to scroll to an item in a list after navigation with Flutter ?
To create rich UX, you need to guide you users as much as possible to help them accomplish "the job to be done".
In today's article, we'll learn how to guide our users through the app by scrolling to a desired resource on a different page
You can find the complete source code here.
Dependencies
To achieve this, we will need the package scrollable_positioned_list which will allows us to control the scroll of our list.
flutter pub add scrollable_positioned_list
Controlling the scroll of the list
You will need to create a scroll controller and a function scrollToTarget
that we will launch after build to scroll to the specific item.
import 'package:flutter/material.dart';
import 'package:flutter_my_awesome_uis/scroll_to_item_in_list_after_redirection/item_data.dart';
import 'package:flutter_my_awesome_uis/scroll_to_item_in_list_after_redirection/post_frame_widget.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
class ListOfAllItemsView extends StatelessWidget {
ListOfAllItemsView({Key? key, required this.itemIdScrollTarget})
: super(key: key);
final String itemIdScrollTarget;
final itemScrollController = ItemScrollController();
void scrollToTarget(int index) {
itemScrollController.scrollTo(
index: index,
duration: const Duration(
milliseconds: 200,
),
);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('List of all items'),
),
body: PostFrameWidget(
callback: () {
final itemToScrollTo = allItems.indexWhere(
(item) => item.id == itemIdScrollTarget,
);
if (itemToScrollTo != -1) {
scrollToTarget(itemToScrollTo);
}
},
child: ScrollablePositionedList.separated(
itemCount: allItems.length,
itemScrollController: itemScrollController,
itemBuilder: (context, index) {
return ListTile(title: Text(allItems[index].text));
},
separatorBuilder: (context, index) {
return const Divider();
}),
));
}
}
Trigger the scroll after build
You may have noticed a special widget here: PostFrameWidget
. This is the widget we will use to trigger our method scrollToTarget
thanks to the callback property. This widget looks like so:
import 'package:flutter/material.dart';
class PostFrameWidget extends StatefulWidget {
const PostFrameWidget({
Key? key,
required this.child,
required this.callback,
}) : super(key: key);
final Widget child;
final Function callback;
State<PostFrameWidget> createState() => _PostFrameStateWidget();
}
class _PostFrameStateWidget extends State<PostFrameWidget> {
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => widget.callback());
}
Widget build(BuildContext context) {
return widget.child;
}
}
We are using the initState
of the StatefulWidget
base class combined with WidgetsBinding.instance.addPostFrameCallback((\_) => widget.callback());
to get the desired behavior.
Everything executed in addPostFrameCallback
will be executed after the child of this widget has been built.
Enjoy !