We all have added appbar in our website where we need to navigate to that section on click of a header. But have you faced issues with it? Sometimes it doesnโt navigate to the exact position, correct? Well, in this article Iโll show you how you can navigate to the exact position no matter the screenย size!
Letโs assume you have a web app that contains an appbar asย follows:
Assume we have some sections like Home, About, Location, Contact and Footer and these sections have non-fixed heights or sections that donโt have the same heights. Now, upon clicking these headers, you want to navigate to respective sections at the exact position. This is something tricky because you canโt calculate how much height needs to be scrolled. So what to do? How can we scroll to the correct position? Is it even possible with Flutter? Well, well, well, letโs try something and check if itโs possibleย ๐
https://medium.com/media/95f14cbc8ad06187290faa11e7985e1d/href
Ok so before we start the main navigation part, letโs create dummy sections as we have in the appbar. I have just created them with varied heights asย follows:
https://medium.com/media/66660a6d2047d60d92bc075bfbcbd922/href
So in the above code, we have added 5 containers with different heights and added a simple text in each. It looks something like the following:
Quite simple, right? As of now, we havenโt added any code for navigation. Now, to navigate to exact position, we are going to make use of Flutterโs hidden gem, GlobalKey. So letโs create a list of global keys which we will later use for navigation.
ListnavigatorKeys = [
GlobalKey(),
GlobalKey(),
GlobalKey(),
GlobalKey(),
GlobalKey(),
];
Now we have made this global so that we can use this list everywhere. Letโs now assign these keys to our sections. Hereโs the updatedย code:
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
key: navigatorKeys[0],
color: Colors.red.shade200,
height: MediaQuery.sizeOf(context).height / 3,
width: MediaQuery.sizeOf(context).width,
child: const Center(child: Text('Home Content')),
),
Container(
key: navigatorKeys[1],
color: Colors.yellow.shade200,
height: MediaQuery.sizeOf(context).height / 2,
width: MediaQuery.sizeOf(context).width,
child: const Center(child: Text('About Content')),
),
Container(
key: navigatorKeys[2],
color: Colors.blue.shade200,
height: MediaQuery.sizeOf(context).height / 4,
width: MediaQuery.sizeOf(context).width,
child: const Center(child: Text('Location')),
),
Container(
key: navigatorKeys[3],
color: Colors.green.shade200,
height: MediaQuery.sizeOf(context).height / 4,
width: MediaQuery.sizeOf(context).width,
child: const Center(child: Text('Contact')),
),
Container(
key: navigatorKeys[4],
color: Colors.pink.shade200,
height: MediaQuery.sizeOf(context).height / 5,
width: MediaQuery.sizeOf(context).width,
child: const Center(child: Text('Footer')),
),
],
),
),
So in the above code, we just assigned the navigatorKeys to the specific sections. You can make this better and more robust by using for-loop or ListView.builder.
Now itโs time to use the keys to scroll to the specific location. But for that, we need to have a scroll controller. So just create a scroll controller and assign it to your SingleChildScrollView! Along with this, also add another container so that we can scroll untilFooter. Otherwise, it will only scroll until the maximum extentย ๐
Now as the next step, we need to write code (or just a function) to navigate to a specific section. The code snippet is veryย small:
void scrollToSection(BuildContext context) {
Scrollable.ensureVisible(
context,
duration: const Duration(milliseconds: 600),
);
}
The above code scrolls the scrollable that encloses the given context to make the given context visible. Further, we just need to call this function. However, the context will be that of the navigator key:
scrollToSection(navigatorKeys[0].currentContext!);
The above code will navigate to the context of the widget to which the 1st navigator key is assigned!
Complete Code
https://medium.com/media/4019ff91b6bee43c88289624c4f8a14c/href
Output
Summary
To summarize, we created a list of global keys and assigned it to each section. To scroll, we used Scrolable.ensureVisible that takes a context and scrolls to that particular context. Hence, we passed the context of that particular section using the key that we assigned to it (navigatorKeys[0].currentContext!). Superย easy!
Hope you enjoyed thisย article!
Doubts? Feel free to drop a message @AbhishekDoshi26
Lazy to read the article? Hereโs the GitHub Repository!
Checkout abhishekdoshi.dev for more infoย ๐
Donโt stop, until you are breathing!๐
– Abhishekย Doshi
Flutter: Seamless Header Navigation from AppBar ๐ was originally published in Google Developer Experts on Medium, where people are continuing the conversation by highlighting and responding to this story.