Welcome to Himdeve development, where we are preparing the best tutorials to make your mobile application development easier and more efficient.
- We add navigation buttons – go back and forward in your browsing history and refresh button to reload the page.
First we open our existing application from the previous tutorial and we open the file shop_page.dart.
We want to add 3 buttons to the top bar of our existing app:
- To go back in the browsing history
- Refresh button
- To go forward in the browsing history
So let’s move on to the code section where we create the Scaffold widget, especially its top bar – AppBar.
We’ll add a new attribute actions here with the navigation controls. Since everything in Flutter is a widget, we can create navigation buttons in the new NavigationControls class that will inherit from the Stateless Widget and we insert the instance of that class as the value of the attribute actions. The parameter of this class will be the Future WebViewController object.
Then, in our project structure, under the presentation layer, we create the components folder and in it a new file navigation_controls.dart.
We open the newly created navigation_controls.dart file.
And we will create the NavigationControls class. The constructor of this class will have the Future object of the WebViewController as an argument.
Subsequently, in the build method of the Stateless Widget, we will create the FutureBuilder widget as in the previous tutorial, where future will be our input parameter for this class. Future generates info about whether WebView Controller is valid.
Consequently, if the WebView Controller is valid, that is, controller.hasData is true, we will return the Row widget in the build method. The Row widget is a Flutter component that displays its children, means other widgets in this widget hierarchy, in a horizontal box.
What’s good to realize is that the Row widget is not scrollable. Even having more widget-descendants in a Row widget than the available space for this widget, is generally considered an error. In that case, it would be a good idea to use the Flutter ListView widget and set the scroll direction horizontally using the ListView attribute scrollDirection (scrollDirection: Axis.horizontal).
Our Row widget will have 3 additional widgets in its widget hierarchy that will represent the 3 navigation buttons mentioned in the first goal of this tutorial.
To go back in the browsing history
The first button in our navigation field will be: To go back in the browsing history. To do this, we create the _buildHistoryBackBtn method, which returns the FlatButton widget. This method has the BuildContext and Snapshot of the WebViewController as the parameters.
In this case, we want this button to consist of an icon representing the back arrow and the text with the title ‘back‘. Therefore, we add the horizontal Row widget to the child attribute of this button to insert the icon and text.
In OnPressed method of this button, it means on the interaction of clicking to this button, we will ask WebViewController if it has data to go backward in its browsing history.
And if it does, we call the WebViewController method:
If it doesn’t, we’ll display a Snackbar with the information that there is no backward browsing history.
Note again that WebViewController’s method – controller.data.canGoBack() needs to be awaited, it means it needs to wait until the Future value, returned by this call, is resolved.
To go forward in the browsing history
This method looks almost the same as the method representing going backwards in history. Just the text and icon of the button as well as the info about that there is no forward browsing history will change. And also the WebViewController methods – canGoForward() and goForward() are used. The name of this method is _buildHistoryForwardBtn.
For the refresh button we create the method _buildReloadBtn, which will have only one input parameter, which is a SnapShot of the WebViewController.
This method returns an IconButton widget which has a refresh icon for the button as well as onPressed attribute representing a callback method to reload the page in WebView using the WebViewController method:
Then we return to the shop_page.dart file to import the NavigationControls class.
In the _ShopPageState class, in the _buildWebView method for the WebView widget, we set the navigationDelegate attribute, which returns a callback method representing the navigation request of a web page change in WebView.
To make this request, we will create a _buildNavigationDecision function that represents an example of how you can manage a web page change request directly in Flutter.
In our case, we will give an example when a user clicks on /my-account sub-page in our store, where we disable this request in Flutter and we display a Snackbar informing that the user does not have the rights to view this sub-page.
What is interesting to note here is that to show a SnackBar cannot be done classically via Scaffold.of(context).showSnackBar, which would find the nearest ancestor of Scaffold in this widget hierarchy. Because we would get an exception that Scaffold.of was called with a context that doesn’t contain Scaffold. And that is because we would try to use the context of widget that created the instance of Scaffold, not its child. Scaffold.of(context) only works if we have a context of widget-child in this widget hierarchy under the Scaffold.
Therefore, we will use a different approach by defining the GlobalKey for Scaffold. And then we can use the globalKey.currentState.showSnackBar command to display the desired SnackBar.
And our goal will then be to rewrite the title bar at the top of our application based on the title of the page we just loaded.
Future – Then method
First we have to evaluate our WebViewController encapsulated into Completer to get the WebViewController value directly. So far, we have done this with FutureBuilder. However, in this case, this is unnecessary as we are not building other UI widgets in this method. So we can use another way to get the WebViewController value by using the Then method, which is the callback of the Future object and is called when the Future of that object is evaluated.
Then the whole method _showPageTitle looks like this:
And with this is our third part of this first series of Flutter Tutorials completed and of course you can find the complete source code on the githube.