My first Flutter app - Main image

Intermediate

My first Flutter app

I build my first Flutter app to discover what Flutter is all about. And I like it so far! Discover all the basics with examples.

Miha Cirman - CodeBrainer
Miha Cirman
22 min read

 

This is a story about my first Flutter app; what I thought Flutter was and what I expected from it. I have loved mobile development for a long time now, it just seems great to have all your applications on the go, all your notes, all documents,... It made sense to me even before it was possible.

I started to follow Flutter a while ago, but I did not have the will to learn a new programming language at the time. One programming language per year seems enough and Kotlin got selected for 2017/18.

But, I just didn’t  want to miss the train altogether, that is why I was keen on all the development that was happening around Flutter. My interest got higher when the Hummingbird was introduced, being an Angular developer as well, this was the way I suspected them to go. This would mean that you can build real multi-platform projects with Flutter (spoiler alert, we are still not there yet, but getting better by the minute)

Flutter, since then, got pretty good and it was time to give it a go. But nothing is as simple as it seems.

 

Goals for my first Flutter app 

With my first flutter app I want to show (explain):

  • What Flutter is all about
  • Discuss some myths
  • How to make the first screen
  • Display data on screen
  • What are states in Flutter
  • How to store data
  • Request data from REST API

 

My first mobile application 

I built my first mobile application a really long time ago, back in 2006 in cooperation with our biggest mobile provider. I was a developer for the Slovenian Golf Association information system back then, and we had a really popular web site at the time. So we decided to offer some of the information on mobile as well. What was great is that we knew that we wanted; a personalized experience when nobody wanted to do so.

We wanted the screens to be simple and personalized, in a way that a user would only see his/her results. These were the times when you only had a few lines of display to show all the data, images were not on a roadmap, since mobile data was very expensive (we paid for kB at the time)

We knew that we wanted a golf app, so we built our first prototype using Corona (in 2010), and rebuilt it later in 2011 and built an iOS native mobile app (build with ObjC in XCode, when we still had to use releases). It was an app for your golf buddies to follow your score. Now only a few users are left on that app, but we are stuck with this legacy version of the app from then. 

2010 was the year when my brother and I started our mobile development venture, we wanted to build a tilt game. But how, where to start?

Programming is a skill best acquired by practice and example rather than from books. Have a look at our Android Development course and get the skills you need.

Start Now

My first multi-platform development experiences

When I talk about my first Flutter app it is safe to say, that I want Flutter for the multi-platform appeal. But my first multi-platform development dates back to 2010 when I started to develop a game with Corona SDK.

Corona SDK is a LUA based multi-platform development SDK (now they call themselves: The 2d game engine). Everything was very good, development was pretty easy and fast, since LUA enables quick prototypes with dynamic types and all the features you expect from a scripting language. 

Corona was great for games, but very bad for business applications, so we had to move our golf app to native iOS.

Soon after that we got our first custom order to develop an app. The app had to run on both platforms, Android and iOS (Android was fairly new at the time).

 

Our proprietary multi-platform development SDK and environment 

I already knew what I wanted from multi-platform development back in 2012. Not to mention, that there were not a lot of multi-platform tools around. But I just knew that we have to go native all the way, and this is just what we did. 

This was hard, I must say, to develop your own development environment and to develop custom projects at the same time. But I must say that we had a vision we did not know how to sell at the time. Just to explain, we are still very excited about hot reload from Flutter, we had it back then, our framework was able to do hot reload on the app, you could change the UI and change the behaviour from a web interface. The idea was for a designer to have more control over UX and UI.

To make a long story short I love multi-platform development, but I also know what I want from it, so I had to pass on quite a few. I code in JavaScript quite a lot, but using JS for mobile development just does not make sense to me, and with that statement, most multi-platform initiatives are tossed away.

 

About Flutter 

"Flutter is an app SDK for building high-performance, high-fidelity apps for iOS and Android from a single codebase"; this is a quote from the Flutter website. They say that the goal is to enable developers to deliver apps that feel natural.

"Apps that feel natural"; says a lot about what Flutter really is. They are working really hard to make it seem like apps are natural, and I must say it does feel so. But this approach will get iOS perfections going nuts. In Flutters’ defense, you have the Cupertino library to make proper native UI components and you can add native code at will.

 

Pros and cons of Flutter

Pros of Flutter

  • Made by Google, this means that a lot of development power is behind the project with their developers and with the support of community. 
  • I love Angular and Flutter just feels like a home away from home for me. The Reactive approach is slowly creeping in.
  • Multi-platform on steroids, this means that we have Mobile (iOS and Android), Desktop and Web all sharing a single language and most of the libraries/frameworks.
  • Hot reload; we all love hot reload, i hope it just improves, maybe this is the function that Android developers were always craving for since Instant Run has a mind of its own
  • A lot of Widgets (UI Components)
  • Everything’s a widget

Cons of Flutter

  • Google is known for killing their projects, hopefully this is not the case, since Dart is very popular with Google developers
  • Dart, another language to learn; would love if this was in Kotlin. But it is not that far, they do share a lot of concepts.
  • No IDE yet, but it works in Android Studio (which I love) and from Visual Studio Code (which I also love)
  • Mac's are pricey and you need a Mac to build a project (or do you?
  • No clear way to structure projects. As developing tools evolve so does the community and with that architecture for projects and code. I'm still looking for a good way to structure folders or project organization. How to split UI code and business logic (models, controllers,...)

 

Myths about Flutter

  • Dart is a strange language; what bothered me the most was the coloring after I made myself feel at home, writing was natural in other words similar to Kotlin
  • Reminds me of React Native. Well this kind of makes sense, since they claim: "a modern framework that takes inspiration from React"
  • Huge APKs, for earlier version APKs were bigger, now there are only a few MB of difference. Which is not that bad if you consider savings in development. 
  • UI components are rendered by Flutter. Everything has a native code but still Flutter renders UI components, they promise to keep it up to date, but there can be a lag. Then again it is not all bad, this is very good for material design, and you can still use iOS native elements (by using the Cupertino library).
  • Widgets tree is hard to read?
  • Not mature enough? In my opinion Flutter is ready to try, it's perfect for simple business apps that need to run on both platforms, or for a simple Android app, that can also run on iOS, but it is not a demand.
    • One statement; that there is no support for peripheral hardware. For example, I can say that there is great support for Bluetooth (tested by the team of BuWizz, best lego brick)
  • The community is still small and bits and pieces are missing; the community is growing fast and there is a lot of fuzz going on. I still found most of the solutions within the core team on their medium topic.

 

Apps made in Flutter

I'm certain that you can build a great app in Flutter, there are many elements there that will make your life easier as well, but we are still waiting for major supporters of Flutter to adopt it's framework. The Best examples I could find are:

Popular apps made in Flutter:

  • Google ads (they are using it)
  • Alibaba
  • Reflectly

You can get a bigger list of apps made in Flutter at Its All Widgets.

 

What will my first Flutter app do?

My first Flutter app is a Golf application. I thought long and hard about this and it is a perfect project for getting to know Flutter. I've done so many of them over the years that I can think about the implementation without thinking about what it does.

Let me explain what is the goal. In golf you have one or more players in the game, and you play 18 holes each. To play you have to go to a course and a course has 18 holes, each with a par and HCP info. HCP is an order of holes by difficulty. To make golf more fun, players track a few more statistics; one is sendie (when you hit the ball into a bunker and still make a par) and putts (number of putts per hole). My first flutter app sketch

There are a lot of challenges with this simple screen. This screen only represents 1 hole, for one player. So we need to scroll in both directions. This is also a lot of inputs, that we need to handle at the same time.

 

Components for my first Flutter app

Now that we know what my first Flutter app is supposed to do, we can break it into components. Bare in mind that these are only base components to showcase most of the Flutter, to make a complete app, you need some more.

UI Components:

  • Single hole result
    • Keyboard thingy you see on the sketch
  • Player all the holes
    • 18 keyboards for a single player (swipe left/right)
  • All the players
    • Bunch of players swipe up/down

Models:

  • Game
  • Hole
  • HoleScore
  • Player
  • PlayerScore
  • Playground

 

Widgets

In Flutter widgets are almost everything. I would split them into:

  • UI and 
  • non-UI widgets. 

UI widgets display some information on screen, or just make padding, spacing,... Non-UI widgets takes care of gestures and states for UI widgets. 

Check the good list of UI widgets. There are a lot of UI widgets ready for us to use, and I really appreciate that, since most of the time getting an app to implement features is more important for me than getting them to look perfect. Don't get me wrong, I do want to build a nice app, but “perfect” takes a lot of time.

We show how to build the first screens of widgets later in the article, so just bear with us a little bit longer.

We have one more split of widgets; stateful and stateless widgets.

Widgets according to the state:

  • Stateless
  • Stateful
  • InheritedWidgets

Widgets and states are one of the most important concepts in Flutter. You need a bit of practice to master, but splitting state and the UI representation of data is a good thing.

Programming is a skill best acquired by practice and example rather than from books. Have a look at our Android Development course and get the skills you need.

Start Now

Stateless widgets - making our first Flutter UI 

Making a UI for my first Flutter app was not that hard, but still, it takes some adjusting to the way Flutter works. What bothers me the most is that the UI is stuck in code (it's a class), not some separate file. Separating UI and let business logic makes a lot of sense.

Let me illustrate with an example for a simple title. This is the title on the top of the screen, it shows a players name, current hole and the player's score. 

Stateless widgets

This example shows two things:

  • How you can make a clean UI widget; meaning that the class is all about the UI components that displays data, it is a component that in a sense does nothing
  • How does InheritedWidget looks in action (we show this later) 

Here is a more elaborate example that shows a common UI interface for a screen. I'm only showing the build method here, I have repeated row closed to focus on main elements.

 Stateless widgets 01

Stateless widgets example

Basic elements for this screen are:

  • Scaffold - a widget for material app look like scaffolding, that enables us to add AppBar
  • AppBar - a bar at the top of the application, that has a title, back button (if appropriate) and action buttons or menu.
  • Column and Row -  widgets  enables us to position elements on the screen, maybe in a little bit of webby way. The great thing is that it is very fast for making a prototype of the screen. 
  • I got used to working with ConstraintLayout a lot and ConstraintLayout makes more sense to me, but to make them work for me, you need a good IDE (it took Android Studio several versions to get there)
  • Padding - one thing I wanted to show is a padding and how padding is a widget as well, all you need is to enclose your elements with Padding and you have a bit of spacing for you elements
  • Text - is the most used element, as it shows the text on the screen.
  • TextField - is an input field for text. It also has the ability to change the keyboard (keyboardType and TextInputType) and change the type of input as well.

I have seen some Flutter enthusiasts argue that this code looks a bit like XML, for me it does not. I'm not saying that it is worse or better, it just feels more like tinkering with the code, than making a user interface. 

States 

What is state? State is an object that holds information about some kind of interaction. So why do we have states? In my opinion states are here just to make stateless widgets possible and make an average app more responsive.

We have already shown, how you can put a UI code into a separate file, but let's show how simple a Stateful widget would look like. Flutter app stateless states

This is just the simplest example of Flutter StatefulWidget I could think of that is good enough to explain everything, and that you can play around ticking checkboxes, again and again, and again...

We need two classes:

  • Simple is the actual class you will call. For example, when clicking on a button
  • SimpleState is a class that holds value and in our case also displays the value using build method

This example illustrates that even a checkbox won't change if you do not have a state. I've created a property named checkedString, to centralize text for the checkbox value.

Call setState method and magic happens

The important part is the setState.

Call setstate

We need to call setState in order to change our state, this method will execute the build for this state.

InheritedWidget - spreading information across the widget tree

The problem with states linked to a single widget is that it is hard to transfer data from one widget in the tree to another. We show this in my first Flutter app using information for the Game. We could do this by accessing the state of the parent widget (or ancestor), but then we depend on the build of the parent being called to refresh the component.

Inherited widgets solve the problem of letting offsprings (childs) widgets know, that the state has been changed.

Let me illustrate the role of InheritedWidget by showing, how does the call of our GameController look like.Call inheritedwidget

I named my class GameController to illustrate that it does not have anything to do with the user interface, the whole purpose of this class is to hold the state of the game. All the widgets that will show anything will be the widgets that are children from our GameController widget. In a sense GameController sits above all widgets that will do the work.

What does a GameController do? Flutter app GameController

GameController holds a state for all the widgets below it. There is an Important function at the end of the class, called of, it converts the context and gets our InheritedWidget 

How does the InheritedWidget looks like? 

InheritedWidget

In InheritedWidget we only have data that we want to transfer over the widgets. In our case it is a state (or service) to work with our Game object.

Example of the State 

Most of the time it is easier to understand, if you see an example of a real class, so that you can see what kind of method or properties will arise from all the classes.

Example of the State

In our case we have a method for updating the score, for loading and saving the game, getting the current player and a few more...

There is one more trick at the end, with passing widget.child in the build method.

We know what widgets are now, and how you can "share" data between widgets in a widget tree.

 

Parsing and storing data 

A very important aspect of programming that I wanted to research with my first Flutter app is how to parse data from a server, in other words working with a JSON and serialization of data. Next is what is the simplest way to store data.

Whenever this is possible I try to store data in the most simplest way. On mobile there is a good solution to get you started, and I know it works on all platforms, SharedPreferences. But you need a string for that.

Knowing how to work with a JSON enables you to store data into a string or convert the string from a server to data for your application to consume.

 

Working with JSON

We are in luck once again as flutter has a built-in library (dart:convert) that does JSON encoding and decoding for us.

To start talking about JSON we need a "data" class. We will use the Player class for this, since it is very easy to understand.

Working with JSON 

Player has only 3 fields, name, HCP and playing HCP. We added a constructor for the ease of use. Now we have a base to add the toJson() function.

Let's talk about the toJson() function. This is a function where you can implement serialization for JSON. Player is a simple class so all we need is link data values. We need a bit more work for complex types. See below.

Working with JSON 01

Converting from JSON to objects we need to implement the fromJson method. In our case Player.fromJson.

Working with JSON 02

Handling arrays in JSON 

We have a class Playground that has a name and an array of Holes. This is a nice example how to encode and decode arrays. Here is the code for the class.

 class Playground

So how do methods look like. toJson stays almost the same.toJson

The important thing is that we also need to implement the toJson method for the Hole class as well. The magic happens and we get a string for a playground. 

Things change a bit for decoding a string. In order to read the array we need a loop that will convert all the JSON objects into objects of a type Hole.

 type Hole 

Shared Preferences - Persistence storage with key-value

For Android and iOS we have a simple solution to store key-value pairs, SharedPreferences for Android and NSUserDefaults for iOS. Using a JSON string and Sharedpreferences can be used for a simple storage for my first Flutter app.

With implementation of classes and functions to encode/decode the JSON we are also one step further to using advanced storage, like SQLite (there is a good plugin for flutter, sqflite, not an official one, but mentioned in documents)

In order to use shared preferences in Flutter we need to add a plugin.Shared Preferences add plugin

We place this plugin inside pubspec/dependencies. Shared preferences plugin inside pubspec

Straightforward if we take into account, that it will work on all platforms. This is one of the official plugins, to see more here is a list of official plugins.

Now that we have a plugin we need to get an instance to the shared preferences. When we do we can store values. We can store primitive types, int, double, bool, string, and stringList

We are storing the whole game using the JSON string here:

 Storing using the JSON string

For load, it is almost the same procedure:

Load using the JSON string

As I said, JSON and storing data in Shared Preferences is a stepping stone to the SQLite storage. But having JSON implemented, opens another door; communication with server.

 

Making REST API calls

Making a call to a REST API is one of the first goals I had for my first Flutter app. Part of my research was a way to mock a REST API. I want a simple and straightforward solution and the ability to serve custom data.

MockApi is a great service for making mockup APIs that I found. All you need is to add a project and a service. If you have a simple data structure it can also generate data for you. It can also create mock data using Faker.js, a library that can generate massive amounts of fake data for you. After all, it is great that you can play with types like dates in future, in the past, names,... It really makes believable data for you to play with. 

This is a simplified version of data that we will receive with the GET call to our mockup API.  Normally playgrounds have a bit more characteristics, also there is a minimum of 9 holes per playground. But this JSON illustrates the data that we will receive.

 Making REST API calls

We make a call using http.get and URL to our REST API service.

Making REST API using http.get

It looks simple enough, we return value as a Future. This is a Dart way of returning asynchronous values. Future represents a potential value (or error) available at some time in the future.

We can use a Future in our advantage for showing a list of playgrounds we received.

Programming is a skill best acquired by practice and example rather than from books. Have a look at our Android Development course and get the skills you need.

Start Now

Showing list of items using Feature and REST API get

It is easier to explain how it works, if you have a screen in mind. It's a simple screen with a list of playgrounds (we display name, and par sum) with the search input field at the top. Showing list of items

We have a great widget for exactly this kind of calls. It is called FutureBuilder.

 Showing list of items code

There are a few elements to FutureBuilder; first is future. This is a Future that will return the value or list of elements, any type you need. 

Next is builder. Builder will expose data in the form of a snapshot. We can check if there was a successful call with hasData property, and we can also show an error.

In the end the FutureBuilder returns a widget, or a list of widgets (list of ListTiles) in our case.

We added another level to it using the filterPlaygrounds function, that will also filter playgrounds using a query. This filter illustrates, how you can take a list of objects and show only the ones that a user is looking for.

Showing list of items filterVariable search that holds query string and variable playgroundsFuture are both part of the state. It is important, that we initialize playgroundsFuture in the initState, this will make our FutureBuilder call REST API only once.

At the end of the builder definition is one more hidden gem. CircularProgressIndicator, this is a loader animation (circular progress indicator). It's a simple implementation for a great effect.

 

Conclusion 

I have learned a lot building my first Flutter app. I must say that the more I build for flutter the more I like it. It has so much widgets ready to use, that it makes creating simple application a breeze. For me this was a month's worth of effort (20 days to be exact), if you take into account that I knew nothing about Flutter at the time my first Flutter app already does quite a few things:

  • saves and loads data (making this a usable app)
  • retrieves data from server
  • It has a complex interface for entering data, but simple for a user to use
  • This app is ready for Android and iOS

It is surprising that I got that far in such a short time. There is a long way to go as well.

Here at CodeBrainer we strive to make are blog post as helpful as possible. Please let me know if there is anything you are still curious about, if there is any error or a feature you would add. And please share it!