An example app showcasing the PageView widget
With the very growing popularity of Flutter, you’ll find more and more blogs, medium articles, and YouTube videos out there on how to use Flutter’s ever-growing number of widgets. With that, I’ve pivoted in my efforts and now write articles more on the implementation of those widgets while possibly referencing any articles and or videos now out there on the subject.
I mean, why repeat what’s already been said? They’ve already describe a widget’s many parameters and how to use them, and so my articles will now mainly involve ‘looking under the hood’ describing how those many parameters are applied— giving you a more in-depth appreciation of a widget’s inner workings. It’s hoped these articles will only help you become a more accomplished Flutter developer.
Today, I’ve chosen the PageView widget and, of course, I quickly found some fantastic articles and YouTube videos about it. In fact, I’ve decided to write two articles about the PageView widget. As promised, there will be an article illustrating how the PageView’s parameter values are eventually applied to present its intended function, however, this first article will actually showcase those articles and videos I found about the PageView widget in the form of my own example app. One that I’ve written and will present to you here.
With the permission of each of the original authors, I’ve taken the very example code from these articles and videos and consolidated them into one app. This app allows a user to then readily change a PageView widget’s parameter settings to see the results in a working app. Actually in this case, in two working apps. Ones that I found on YouTube.
Tensor and Johannes
I’ve been following these two gentlemen almost from the beginning. Their video productions are top-notch. I’d certainly recommend you subscribe to them. In no particular order, you have one video from the Tensor Programming channel, and the other from Johannes Milke’s own YouTube channel.
I’ve taken the corresponding example apps from these two and placed them into one app called, pageview_example. As for articles, I would recommend (again, in no particular order) the articles from Suragch and Deven Joshi.
I Like Screenshots. Click For Gists.
As always, I prefer using screenshots in my articles over gists to show concepts rather than just show code. I find them easier to work with frankly. However, you can click or tap on these screenshots to see the code in a gist or in Github. Further, it’s better to read this article about mobile development on your computer than on your phone. Besides, we program mostly on our computers — not on our phones. Not yet anyway.
No Moving Pictures, No Social Media
There will be gif files in this article demonstrating aspects of the topic at hand. However, it’s said viewing such gif files is not possible when reading this article on platforms like Instagram, Facebook, etc. They may come out as static pictures or simply blank placeholders. Please, be aware of this and maybe read this article on medium.com
I would say to read and watch the material mentioned above first. They don’t take long and, as I’ve implied, are very informative. I invite you to then download the example app that utilizes much of the sample code covered and try out the many settings in the app’s drawer. I suspect you’ll then get to know all you’ll need to know about the PageView widget.
Almost every setting demonstrated in the app is presented below in order of the widget’s list of parameters. You’ll readily see what options are available to you, and it’s hoped it will help you determine if a PageView would be just the thing for your next app.
Horizontal or Vertical
The Order of Things
Tap, reverse, and you’ll find the pages are now in reverse order.
You can control which page will first appear, as well as their actual width.
How the pages move and what happens when reaching the end or beginning.
To Snap Or Not
If set to false, with one swipe pages can easily go by and not snap into place.
With Every New Page
A Callback function can be called with every new page.
How It Transitions
Near the end of his article, Deven Joshi introduces some wonderful ‘transition’ examples that you could implement for your own pageviews. It’s the way the swiping from one page to another is depicted graphically and makes for some interesting effects. Download pageview_example and try it for yourself.
So there you go. Flutter’s PageView widget provides a very agreeable interface. There’s already great documentation out there regarding this widget. It’s hoped bringing some of them together here with an example app will further convince you of its usefulness.
Again, I was so impressed with the articles and videos already covering the PageView widget, there was no point rehashing the subject. I decided to write up a little app to showcase their own work instead. The rest of this article will present what was done to quickly do just that. Now, I didn’t want to make a big production of it when showcasing these other apps, and so some shortcuts were made that I wish noted. I wrote code, frankly, I would not write in my production code.
For example, the PageView widget used in my little example app was key in reflecting the settings depicted in my app’s Drawer widget to both Johannes and Tensor’s example apps in which my app encapsulates. The screenshots below highlight both Johannes and Tensor’s PageView widgets. As it happens, they both used the ‘builder’ constructor found in the PageView class. However, the trick here is that that’s not actually the PageView class. It’s a subclass by the same name! Yikes!!
Again, just to get this up and running, I simply created a subclass of the StatelessWidget, PageView, and overridden all its fields. Now you‘re allowed to do this, of course, but it’s certainly not encouraged. Overriding a field or ‘variable shadowing’ can lead to unexpected behaviors and confusion. It’s just bad form. Never mind overriding an established and core Flutter class and yet assign the very same name! To top it off, as you can see in the screenshot below, I’m inheriting an immutable class only to introduce mutable properties. In Flutter, this approach only degrades performance. It’s just not a good practice. And so, this is a case of, ‘Do as I say, not as I do.’ However, doing all this allowed me to quickly incorporate two separate apps sharing a common ‘PageView’ class.
In this bad ‘PageView version,’ the private function, _setPageView, is called in its constructor. It’s this function where all the static fields found in the Drawer class, PageViewDrawer, are reviewed. If one of these static fields is not null, its value is assigned to the PageView’s own overridden field. Otherwise, it retains its original field value. Yup, quick and dirty.
The set_state package was used to readily reference the first State object, _MyAppState. This is so to update the Drawer when a user taps on one of its switches and or sliders. The SetState class is also used to update the PageView of whichever example app currently up and running with its new settings.
Of course, it’s in the first State object, _MyAppState, where the Drawer, PageViewDrawer, is introduced. Again, as a shortcut, I merely wrote a subclass of the Drawer class and overridden its ‘child’ field. It’s filled up with static fields to mirror those in the PageView class so you can easily switch out settings and see what the PageView can do for you. Ugly, but hey! Go big or go home! Right? Again, I’m messing up an immutable class. Not recommended.
The Switches and Sliders corresponding to the PageView properties come from the private functions _switchFunc() and _sliderFunc(). See below.
I will say the RadioButton class I wrote during this process has proven to be useful. I will likely use it in my own apps. Well, at least that’s something.
What’s Your Source?
Note, the files all with the same name called, source.dart, peppered about the app’s directory structure. In the screenshot below, you can see these files highlighted along the left-hand side. I call such files, ‘export files,’ and as it happens in this particular example app, they allow every class access to every other class found in the Dart library files under the app’s directory, src. This approach is akin to Google’s own approach to organizing Dart library packages. With that, you’ll discover many of the Dart library files under the directory, src, has only one lone import statement:
A Source To Everyone
To explain further, the screenshot below is of the file, source.dart, highlighted above under the director named, greg. As you can see, it merely ‘exports’ the remaining Dart library files located in that directory.
This is true for the file, source.dart, found under the directory, johannes. Every Dart file found under the directory, johannes (even those in subdirectories) are simply listed in that one ‘source’ file. The idea being, these ‘export files’ are, in turn, referenced in another export file. That file is also named source.dart (maybe better with a different more distinct name) found in the top directory, src. It is this file that is then imported in specific Dart files requiring access, of course, to the relevant code.
The Source Of All Things
As you see below on the left-hand side, the Dart library file also named source.dart and found in the directory, src, contains the other two ‘source’ files. Tensor’s example app consisted of only one file, main.dart, and so a ‘source’ file for that app wasn’t really necessary. However, its one file is, of course, exported here as is all the other source code required to run this app — including Flutter’s own framework and any third-party Dart packages. Note, the Flutter framework’s own class, PageView, is hidden here because my own version is to be used.
This arrangement makes it very easy for subsequent developers who may, for example, have to maintain apps such as this. What source code is to be utilized is all concisely found in one place. Further allowing for one import statement in many instances.
In anticipation of the second article with the emphasis now more on how the Flutter framework actually implements this widget’s many named parameters, here’s an excerpt of what you might see.
When using a PageView, and you swipe to the end/beginning of the list, a visual effect occurs highlighting the event. Such visual effects are part of what is defined as the widget’s ‘scrolling physics.’ The one ‘physics’ defined for the PageView widget comes from the class, PageScrollPhysics.
In other words, if you don’t explicitly pass a ‘Scrolling Physics’ object using the named parameter, physics, (see below) when instantiating a PageView widget, the class, PageScrollPhysics, is used by default with its prominent trait being the ‘snapping’ of pages into place with every new swipe. In fact, in the next article, I’ll explain it’ll always be that trait — unless the parameter, pageSnapping, is set to False.
Note, the screenshot below explicitly turns off the ‘page snapping’ effect, but I’ll show ‘under the hood’ in the next article that, since we’re then explicitly passing the ‘PageScrollPhysics’ object, we’ll still have a lot of snapping going on. See you then.
Follow Flutter Community on Twitter: https://www.twitter.com/FlutterComm