Image taken from https://flutter.dev

Building Cryptocurrency Pricing App with Flutter

Bilguun Batbold
Quick Code
Published in
7 min readMar 15, 2019

--

Flutter allows you to build beautiful native apps on iOS and Android from a single codebase

I’ve come across Google’s new open-source toolkit for cross-platform development recently, and decided to give it a try. You can read about the various benefits here (spoiler, it seems really great), but I thought I would share with you on how to get started with Flutter with something other than their tutorial.

We will be creating a Cryptocurrency Price List app with pull-to-refresh functionality and also to keep track of your favourite Cryptocurrencies.

What we will be doing in this tutorial.

Prerequisites

I will be using a Macbook with iOS simulator to build this app. Feel free to use Windows machine and an Android emulator.

Before we begin, head over to Flutter and install Flutter and various dependencies. While you are at it, grab your favourite IDE and set it up to use with flutter (we will be using VS Code in this tutorial).

Let’s get started!

In VS Code (follow steps here if needed), search for Flutter New Project to create a new flutter project. Name it crypto_list and let flutter initialise the project for us.

A file main.dart is created, and this will be the point of entry for our app. We will be building the app from scratch, so go ahead and delete all the code there.

This is how your IDE should look at this point.

Creating basic UI

When you start the app, the code will be executed from the main function. So let’s go ahead and create it as above.

open -a Simulator
flutter run

This opens the default simulator used on your machine, and runs the application. Run it and it should show the following

It is ugly but gets the job done.

Ok great! You have build your first UI using flutter! It is quite ugly now so let’s create couple of widgets to beautify our app.

Adding widgets

Stateless widgets are immutable, meaning that their properties can’t change — all values are final

Stateful widgets maintain state that might change during the lifetime of the widget. Implementing a stateful widget requires at least two classes: 1) a StatefulWidget class that creates an instance of 2) a State class. The StatefulWidget class is, itself, immutable, but the State class persists over the lifetime of the widget.

Edit our code to be like what is shown above.

What we have done is:

  1. Add a stateful widget CryptoList which creates its state class CryptoListState
  2. Most of the logic will be stored in CryptoListState and CryptoList just creates its State class
  3. build to describe how the widget will look. Here we are returning Scaffold which creates an appBar with title and icons and body with centralised text.

Press r to reload changes or R to hot restart (and rebuild state)

Looks so much prettier!

With Scaffold we have infinitely improved the overall UI of our app. Remember we used theme in the MyApp class? It was used to set the primary colour of our app, (and by extension appBar's colour).

Feel free to change it accordingly, for eg new ThemeData(primaryColor: Colors.orange) but we will continue using white.

Primary colour changed to orange.

Making HTTP request to get data

Before we add a list of Cryptocurrencies into the body of our view, let’s first get all the data required for us to continue.

import 'package:flutter/material.dart';
import 'dart:math';
import 'dart:async';
import 'dart:convert';
import 'dart:core';
import 'package:http/http.dart' as http;

Import all these modules we will be using at the top of your main.dart file. Find the file pubspec.yaml and http: ^0.12.0+1 (which is required to make http requests) so that it looks like this:

Once you add, flutter will automatically install the dependency
  1. pubspec is where the packages metadata is stored
  2. dart:async allows writing asynchronous code using Future class
  3. dart:convert allows decoding JSON response
  4. package:http/http.dart allows making http requests
  5. dart:math and dart:code provides some helper functions to manipulate data

Update the code as shown above. Please read the comments on what is added. Essentially, we have asked our widget to execute getCryptoPrices when the state is initialized. We then perform an async operation to get the data from an api, and set state of cryptoList.

Perform hot restart by pressing R

Output of the app now. All the required data is available for us to use.

Great! Our data is available for us to use. We can now generate UI to show this data.

Creating ListView

Update your code with the one shown above. A lot of codes have been added, but I have tried to add as much comments as possible to make it understandable. Here is what we have done:

  1. Replace our Scaffold body with _buildCryptoList. This returns a ListView. Rows are build using _buildRow
  2. _buildRow takes in the each cryptocurrency object with colour. It builds a row accordingly: Avatar, Title, Subtitle and Icon
  3. _fav handles when the heart icon is clicked. _saved contains the list of crypto objects we have favourited.

Perform hot restart by pressing R

Looks so much better!

Great! You have now built an extremely decent looking UI that contains real data about various Cryptocurrencies. If you could not understand the code, it is okay! Take your time and with enough practice, you will get the hang of it. Else, feel free to leave a comment below.

Adding Loading Bar

If you noticed, when you restart the app, there is a brief second where an error is displayed. This is because when the getCryptoPrices is called, the _cryptoList state, which is used to build the list view, is not set, and thus you get an error until the state is set. Let’s edit the code to show an loading bar until _cryptoList is set.

Update the code with this. Instead of directly calling the _buildCryptoList in the body of our Scaffold we are calling another function _getMainBody.

In getCryptoPrices we have also set _loadingto true before we make a request and _loadingto false after have completed the request. _getMainBody then checks and returns a progress bar if _loading is true.

When you run the app, you should see a circular progress indicator for a split second instead of an error page we saw earlier.

Centralised loading bar when an API is in progress

Pull to Refresh

We have a decently working app right now. Since I have had prior experience building iOS apps, I wanted to see how it would be to mimic some functionalities. One of the most commonly used functionalities is Pull to Refresh.

Turns out, it is actually very simple.

Replace the _getMainBody with the above function. What it does is, instead of returning ListView directly, it wraps it around RefreshIndicator which allows pull to refresh possible. We then point the onRefresh to the function where we make the api call.

Pull down to refresh the data

This is why we needed our widget to be Stateful. When the data is changed, either through polling or serve pushes, we want the data to change and UI to be rendered accordingly. If we just want to display the data once for the duration of the application, we can make our widget to be Stateless.

Pushing New View

We have mentioned earlier that we want to be able to view the favourited Cryptocurrencies. So let’s implement that.

Implement _pushSaved function we have declared previously as above. I’ve written in comments what is happening. Basically we get each saved item and build a new list and pass it to the new route’s Scaffold.

This function is triggered when:

new IconButton(icon: const Icon(Icons.list), onPressed: _pushSaved),

in the home screen. Let’s run the app and see what happens.

First favourite some items and press the top right button
Your favourited items will be visible!

And of course, cross platform framework would not be useful if we cannot run it on both Android and iOS! So here are the Android equivalent screenshots with no code change.

I believe certain customisations are definitely possible to better suit the native looks of each platforms, such as by using cupertino style widgets but that is not covered in this tutorial.

Final Thoughts

This was my first project I have made using Flutter. I have referenced the original sample shown in the official Flutter page, but have extended it to facilitate my own learning. The framework really feels cool, so I might write other complex tutorials in the future.

The full source code can be found here:

If anyone finds these useful, feel free to share this or let me know should there be an error / bad practice / implementations.

Have fun coding!

--

--