Flutter tutorial for beginners: how to develop apps with this Google SDK
If you want to program your own app, there are plenty of options available to you. Builders with ready-to-use app components are very popular due to their ease of use, but frameworks are also becoming increasingly known for making the development process as easy as possible for users. One of the most recent examples is the software development kit (SDK) Flutter developed by Google. This open source framework allows you to develop high-performance mobile apps (for iOS and Android) as well as web and desktop apps in Google’s programming language Dart.
In our Flutter tutorial, we will go over the most important steps for getting started with the Google SDK.
Learning Flutter: the requirements
If you want to learn how to program with Flutter, you do not necessarily need to have any previous experience in app and web development. You do not even need to know anything about the previously mentioned Google programming language Dart. If you are familiar with object-oriented code and basic programming concepts (e.g. variables, loops, and conditional statements), you are already well equipped to work with the framework.
This Flutter tutorial provides you with a basic introduction to the software development kit by programming a simple app that combines words in a random pattern and then displays these combinations. For this, you will need the basic tools for programming with Flutter: the Flutter SDK and an editor. The SDK is available for Windows, macOS, and Linux. You can download the appropriate installation package directly from the official Flutter website.
For the editor, you are free to choose whichever one you want. However, to get an optimal user experience with autocomplete for code, syntax highlighting, and support for debugging and editing widgets, Google recommends using a code editor that has an official Flutter plugin. We have thus opted to use Android Studio in our Flutter tutorial. Once you have installed a suitable development environment optimised for developing Android apps, set up the Flutter plugin using the following steps:
- Go to the ‘File’ menu option.
- Click on ‘Settings’ and then select ‘Plugins’.
- Type ‘Dart’ in the search bar. Then, click on the ‘Install’ button for the matching search result to perform the initial installation of the extension for the required programming language Dart.
- Confirm the use of this third-party extension by clicking ‘Accept’.
- Repeat these steps for the search term ‘Flutter’. Once installed, click ‘Restart IDE’ to apply the changes.
For alternatives to Android Studio, Google recommends GNU Emacs, Visual Studio Code or IntelliJ IDEA – all of which have an official Flutter plugin.
Step 1: create your first Flutter app
Once you have installed Flutter and the desired development environment (or editor), you can create your first Flutter application. As previously mentioned, we are using Android Studio in this Flutter tutorial, so we will now launch the IDE for this purpose. From the ‘File’ menu option, first select ‘New’ and then ‘New Flutter Project’ to start a new project based on this app framework.
Select ‘Flutter Application’ as the desired project type and then click ‘Next’. In the configuration menu, define the project name and location for your application. You also have the option of adding a description to the project. In the field labelled ‘Flutter SDK path’, enter the path for the installed Flutter framework.
Finally, click ‘Finish’ to create the new Flutter app. In the main.dart file, the basic working file of a project and of this Flutter tutorial, add the following code to tell the app to display a simple ‘Hello world’ message (you can delete any existing code in the main.dart file):
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: Center(
child: Text('Hello world'),
),
),
);
}
}
Once you have entered this snippet of code, you can view the initial version of your app. In Android Studio, select the desired virtual machine (found under ‘Flutter Device Selection’). Then, click the play button (‘Run main.dart’):
To preview an app in Android Studio, a system image of the desired target platform must be installed. Otherwise, you will not be able to select a virtual test device under ‘Flutter Device Selection’ to test the app. To add one, select ‘Tools’ and then ‘AVD Manager’. Then, click ‘Create Virtual Device’ and install your desired virtual device. You can find detailed instructions on how to create and manage virtual devices in Android Studio in the Android developer forum.
The initial launch and debugging of the app will take some time, so you will have to wait a bit for the welcome message to appear on the screen of your test environment.
Step 2: add an external package
Having gotten a simple initial app up and running in the first step of the Flutter tutorial, we will now extend it with an external package. To be more precise, we now plan to add the words package required for our project’s objective - the project being the app that combines words in a random pattern. In our example, we are using the open source package ‘english_words’ (MIT license) which you can find on the platform pub.dev along with many other open source packages. This module contains over 5,000 of the most commonly used English words which makes it perfect for the purposes of this Flutter tutorial.
Flutter apps use the file pubspec.yaml to manage packages and dependencies. Open this file and add an entry for the language package to the list of dependencies (check that it is up to date; here it is 3.1.5):
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
english_words: ^3.1.5
Then, execute the command ‘flutter pub get’. Android Studio even has a button labelled ‘Pub get’ for this purpose.
Go back to the main working file main.dart and import the language package there:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
You also need to add the following line to the app’s code:
final wordPair = WordPair.random();
Lastly, replace the child entry, which outputs the text ‘Hello world’, with the following entry:
child: Text(wordPair.asPascalCase),
Every time you execute the new updated app code, you will now receive a randomly generated pair of English words.
Step 3: add a stateful widget
Stateless widgets, such as those previously used in this Google Flutter tutorial, are static. They cannot change their state during an app’s runtime. Therefore, this type of widget cannot be modified while the application is running. Stateful widgets, on the other hand, can change their state during an app’s runtime, so it does not have to be static when the app is executed. If you wish to add interactivity to certain parts of your Flutter app, you will need stateful widgets.
In Flutter, widgets are always either stateful or stateless. Typical examples of stateless components include icons, buttons, and text modules, while typical examples of simple stateful widgets include checkboxes, forms, and sliders.
Our example app will also get an interactive widget at this point. For this implementation, at least two classes are required: a StatefulWidget class which in turn generates an instance of a state class.
First, we create a minimal state class called ‘RandomWordsState’ by adding the following code to the end of the main.dart file:
class RandomWordsState extends State<randomwords> {</randomwords>
// TODO Add build() method
}
In this case, the generic state class is explicitly defined for use with the ‘RandomWords’ widget. The stateful widget itself is added to the main.dart file in the next step using the following code (comes before the ‘RandomWordsState’ class in the code):
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => RandomWordsState();
}
When you execute this new app code, Flutter will tell you that there is currently no build() function defined for ‘RandomWordsState’.
In the added code snippet for the state class, you will find the placeholder comment ‘//TODO Add build() method’ in the appropriate location which will now be replaced by the code for the build() function:
class RandomWordsState extends State<randomwords> {</randomwords>
@override
Widget build(BuildContext context) {
final wordPair = WordPair.random();
return Text(wordPair.asPascalCase);
}
}
Lastly, remove the line ‘final wordPair = WordPair.random();’ from the MyApp class and replace the child entry ‘child: Text(wordPair.asPascalCase),’ with ‘child: RandomWords(),’.
When you execute this new code, the virtual test device should still display a word pair, but now it is based on a stateful widget that could potentially allow user interaction.
Step 4: create an infinite scrolling list view
To provide an example of an interactive Flutter widget, we will extend our app in this final part of the Google Flutter tutorial. To be more precise, we will modify the ‘RandomWordsState’ class so that it no longer just displays single word pairs but instead gives the user an infinite list of word pairs to scroll through. In addition, we want to save previously suggested word pairs (to avoid duplicate entries) and to increase the font size of the results.
Let us start with the last two points (i.e. saving the results and changing the font size) by adding a _suggestions list and a _biggerFont variable:
class RandomWordsState extends State<randomwords> {</randomwords>
final _suggestions = <wordpair>[];</wordpair>
final _biggerFont = const TextStyle(fontSize: 18.0);
}
Then, add the appropriate _buildSuggestions() function to the ‘RandomWordsState’ class as well:
Widget _buildSuggestions() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, i) {
if (i.isOdd) return Divider();
final index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
The function shown above extends the app with several features. This includes the listing of word pairs (List.View) which is made easier to read by a one-pixel divider (Divider). It also defines that an additional ten suggestions will be presented (line: _suggestions.addAll) as soon as the user has reached the end of the currently displayed list.
Another basic component of this extended widget is the _buildRow() function which is called once per word pair and presents each pair as a ListTile. We will implement this function in the next step:
Widget _buildRow(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
The build() method we implemented when we generated the stateful widget (step 3) must now be told to use the buildSuggestions() function. The previous content of this method must, therefore, be replaced with the following code:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Word Generator'),
),
body: _buildSuggestions(),
);
}
Lastly, update the build() method in the MyApp class by changing the title and defining in the home entry that it is a RandomWords widget:
title: 'Word Generator',
home: RandomWords(),
If you now execute the code again, the app will run under the new title ‘Word Generator’. In addition, a whole list of word combinations will be displayed which you can scroll through to see more results.
Flutter tutorial summary
Over the course of this Google Flutter tutorial, you have learned the essentials for working with Flutter and how to apply them to make a simple example app. You can of course develop your individual Flutter applications in much greater detail and scope. You can also customise the design once you have gained a deeper understanding of the framework.
To conclude, we shall present you with the complete code for the developed example Android app in the main.dart file:
import 'package:english_words/english_words.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Word Generator',
home: RandomWords(),
);
}
}
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => RandomWordsState();
}
class RandomWordsState extends State<randomwords> {</randomwords>
final _suggestions = <wordpair>[];</wordpair>
final _biggerFont = const TextStyle(fontSize: 18.0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Word Generator'),
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, i) {
if (i.isOdd) return Divider();
final index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
});
}
Widget _buildRow(WordPair pair) {
return ListTile(
title: Text(
pair.asPascalCase,
style: _biggerFont,
),
);
}
}