One week ago, Flutter released its first bêta version at the MWC in Barcelona. The main purpose of this article is to show you how to develop a first fully functional application with Flutter.
This article will be a little bit longer than usual, because it will go through install process and also teach how Flutter works.
We will develop an application displaying to the user a list of posts retrieved from the JSONPlaceholder API.
Flutter is an SDK that allows you to develop native applications for Android, iOS or the next OS of Google: Fuschia. It uses Dart as main programming language.
In order to get Flutter, you will need to clone the official repository. You will also need Android Studio if you want to develop applications for Android, and XCode if you want to develop applications for iOS.
You will also need IntelliJ IDEA (OK, it is not required, but much more useful). Once installed, add the Dart and Flutter plugins to IntelliJ IDEA.
All you have to do is to clone the official repository of Flutter:
git clone -b beta https://github.com/flutter/flutter.git
Then, you will have to add the path to the bin folder of the repository to your PATH environment variable. That’s it, you are now able to develop applications with Flutter.
Even if it’s enough, I really went quickly through the installation procedure in order not to make this article longer than needed. If you want a more complete guide, go to the official documentation.
Let us now open IntelliJ IDEA and create a first project. In the left panel, choose Flutter (if it is not available, please install Flutter and Dart plugins to your IDE).
We will name it as follow:
The editor of IntelliJ opened a file named main.dart
, which is the main file of the application. If you do not already know Dart, don’t panic, it is not required for the rest of this story.
Now, plug an Android or iOS phone in your computer, or run an emulator.
You are now able to run the application by clicking on the run button (with a green triangle) at the top right:
Click on the bottom floating action button in order to increment the number displayed. We will not go deeply into he code for now, but we will instead discover some fun features with Flutter.
As you can see, the primary color of this application is blue. Let us change this color to red. In the main.dart
file, look for the following code:
In this part, replace Colors.blue
by Colors.red
. Flutter allows you to hot reload your application, meaning that nothing will be modified from the current state of the application, but our new code will be applied.
In the application, click on the + bottom floating action button to increment the counter.
Then, on the top right of IntelliJ, click on the Hot Reload button (with a yellow lightning). You will see that the primary color is now red, but the counter remains with same number.
Let us now remove all the content of the main.dart
file. What a better way to learn.
The first thing we will do now is to develop the minimal application, meaning the minimum code to be able to run it. As we will use Material Design for the design of our application, the first thing to do is to import package containing the Material Design Widgets:
Let us now create a class extending StatelessWidget
to make an instance of our application (we will go deeply into what a StatelessWidget
is later in this article):
IntelliJ IDEA displays MyApp underlined in red. Actually StatelessWidget
is an abstract class requiring the implementation of the build()
method. To do so, move your cursor on MyApp and then press Alt+Enter.
Now that we implement the build()
method we can see that it must return a Widget
instance. We will return a MaterialApp
as we are building the application here. To do so, add the following code in the build()
method:
The documentation of MaterialApp
tells us that at least home
, routes
, onGenerateRoute
or builder
must be initialized. We will only define home
property here. It will be the home screen of your application. Because we want our application to be a basic Material Design layout, we will set home
as an empty Scaffold
:
The last thing to do is to tell that when we run main.dart we want to run the MyApp
application. To do so add the following line right after import statements:
You will now be able to run your application. It is only a white screen without any content. So the first thing we will do now is to add the user interface of the application.
We may develop two kind of user interface. A user interface which is not regarding to the current state of the application, or a user interface regarding it.
When talking about states, we are meaning that the user interface may change when an event is triggered. And this exactly what we will do:
Launching application event:- Display the circular progress bar- Run the action to retrieve posts
End of API request:- If success, display the list of posts retrieved- If failure, display a Snackbar with failure message on an empty screen
For now, we only used StatelessWidget
which are, as you can guess, not regarding the state. So lets start by initializing a StatefulWidget
.
Let us add a class extending StatefulWidget
to our application:
As we can see, we have to implement the createState()
method which returns a State
object. So let us create a class extending State
:
As we can see we will have to implement build()
method returning a Widget. In order to do so, let us first create an empty widget (Row
) :
We actually return a Scaffold
object as the toolbar of our application will not change nor depend on the current state. Only its body will depend on the state.
Let us now create a method that will return the Widget to display regarding the current state, and a method that will return the Widget containing the centered circular progress bar:
If you run the application now you will see a circular progress bar in the center.
We will start by defining the Post
object as it is define in the JSONPlaceholder API. To do so, let us create a Post.dart
file with the following content:
We will now define a PostState
class in the same file to degine the current state of the application:
All we have to do now is to define a method in the PostState
class to get the list of Post
from the API. We will see how to do this later because for now we will only return a static list of Post
asynchronously:
Now that it is done let us go back to our PostPageState
class in the main.dart
file to see how to use the class we just defined. We will start by initializing a postState
property in the PostPageState
class:
If IntelliJ IDEA displays
PostState
underlined in red, this means that thePostState
class is not defined in the current file. So you will have to import it. To do so, move the cursor to the red underlined part and press Alt+Enter, then choose Import.
Now, let us define a method for returning a Widget when we successfully get the list of Post
:
All we have to do now is to edit the getCurrentStateWidget()
method to display this Widget if we successfully get the list of Post:
Last thing to do, and maybe the most important one, is to run the request in order to retrieve the list of Post. To do so, we will define a _getPosts()
method and call it when initializing the state:
Et voilà. You can run the application in order to see the result. Actually, there is almost no chance that you see the circular progress bar, even if it is actually displayed. This is because retrieving the list of Post is so fast that it is disappearing almost instantly.
In order to be sure that the circular progress bar is actually displayed, let us retrieve the post from the JSONPlaceholder API. If we take a look at the post service of the API, we can see that it returns a JSON array of Post.
So we will have to start by adding a static method to Post class in order to convert a JSON array of Post to a list of Post
:
We now only have to edit the method retrieving the list of Post
in the PostState
class to actually retrieve it from the API:
You now can run the application and you will see the circular progress bar more or less briefly depending on your internet connection.
For now, we only display the number of posts retrieved but not the list of Post as we expect. To be able to display it, let us edit the _getSuccessStateWidget()
method of the PostPageState
class:
If you run the application again you will see the list of posts.
We have one last thing to do: handling the errors. You can try to run the application in flight mode, and you will see that you will see the circular progres bar indefinitely. We have to return an empty error state:
Now, when an error occurs, an empty screen is displayed. Feel free to change the content in order to display en error empty state screen. But we sayed that we want to display a Snackbar with ability to retry when an error occurs. To do so, let us develop a showError()
and a retry()
method in the PostPageState
class:
As we can see we need a BuildContext
in order to get the ScaffoldState
which is allowing us to make the Snackbar appear and disappear. But we have to use the BuildContext
of a Scaffold
object in order to get the ScaffoldState
. To do so, we will have to edit the build()
method of the PostPageState
class:
Feel free to now run your application in flight mode, the Snackbar should be displayed. If you leave flight mode and then click on RETRY, you should see the list of Post.
So we learned that developing a fully functional application with Flutter is not something that much hard. Every elements of Material Design are provided, and you developed an application with it on both Android and iOS platforms.
All the source code of this project is available on the Feed-Me Flutter project on GitHub.
If you liked this article, feel free to follow me on Twitter to get notified about next ones.