A Beginner’s Guide to Flutter (Part 2)

Deepak Jogi
6 min readAug 27, 2021

This is Part 2 of a Three-Part Guide.

Part 1 : Building the User Interface

Part 2 : Adding Functionality

Part 3 : External Packages and What Next?

Aim of this article

We’ll be making the default flutter app (sort of like a hello world app for flutter). Every time we press the ‘+’ button the value of the counter will increase and it will display the current Value.

Part 2: Adding Functionality

What we’ll be covering in this part

  1. Adding Functionality to our App
  2. Stateful Widgets

Our Code up to this point looks like this

import 'package:flutter/material.dart';void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage()
);
}
}
class HomePage extends StatelessWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Center(
child: Container(
child: Text("Hello World"),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: ()=>{},
),
);
}
}

Our aim is to make a counter app so let us declare a variable that stores the number of times the button has been pressed called counter.

class HomePage extends StatelessWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {

int counter = 0;

return Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Center(
child: Container(
child: Text("Hello World"),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: ()=>{},
),
);
}
}

Now we want to change the “Hello World” text to “The Button was pressed x time”. Notice how we used the ‘$’ sign to reference the variable in the text.

class HomePage extends StatelessWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
int counter = 0; return Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Center(
child: Container(
child: Text("The button was pressed $counter times"),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: ()=>{},
),
);
}
}

Now let’s try a hot reload.

Now our app looks how we want it to look now we should make it update the counter when the ‘+’ button is pressed.

1. Adding Functionality to our App

So we want the counter variable to increase every time we press the ‘+’ button. We can do this by using the onPressed parameter for the FloatingActionButton widget. We had left this as an empty function before but let us give a function that updates the variable counter.

class HomePage extends StatelessWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
int counter = 0;
void incrementCounter(){
counter++;
print("The button was pressed $counter times");
}
return Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Center(
child: Container(
child: Text("The button was pressed $counter times"),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: incrementCounter,
),
);
}
}

Okay let’s run a hot reload (or hot restart)

Now let’s try pressing the ‘+’ button.

As we can see from the output below the variable get’s incremented.

But the counter doesn’t change its number in the device even if you hot reload or hot restart.

Okay, something is definitely wrong here, let’s see why our app won't increment the number.

The Entire Code up to this point looks something like this

class HomePage extends StatelessWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
int counter = 0;
void incrementCounter(){
counter++;
print("The button was pressed $counter times");
}
return Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Center(
child: Container(
child: Text("The button was pressed $counter times"),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: incrementCounter,
),
);
}
}

As we can see the HomePage widget inherits from a stateless widget, so HomePage is a stateless widget. This means that once it has been rendered it won’t change its state. That is why our counter won’t change.

What we need is a Stateful Widget.

2. Stateful Widgets

The widgets whose state can be altered once they are built are called stateful Widgets.

A stateful Widget declaration has the general form

class WidgetName extends StatefulWidget {
const WidgetName({Key? key}) : super(key: key);
@override
_WidgetNameState createState() => _WidgetNameState();
}

class _WidgetNameState extends State<WidgetName> {
@override
Widget build(BuildContext context) {
return Container();
}
}

This can be obtained with the keyword “stful” the same way we used “stless” to create a stateless widget(try this right now).

But in this case, we don’t need to create another stateful widget, flutter allows us to convert a stateless widget into a stateful widget. All we have to do is right-click on the stateless widget.

Click on show context Actions and choose convert to StatefulWidget

Now our stateless widget is converted into a stateful widget.

class HomePage extends StatefulWidget {
const HomePage({
Key? key,
}) : super(key: key);

@override
State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
int counter = 0;

void incrementCounter(){
counter++;
print("The button was pressed $counter times");
}

return Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Center(
child: Container(
child: Text("The button was pressed $counter times"),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: incrementCounter,
),
);
}
}

Now we can change the state of our app.

Do a hot restart(not a reload), Even now if we click on the ‘+’ button our counter doesn’t increase in the app.(try it)

This is because we haven’t set the state of our stateful widget. We can set the state by using the setState() function. We have to set the state of the function and increment the number every time the button is clicked so we have to change our increment function to the following.

class HomePage extends StatefulWidget {
const HomePage({
Key? key,
}) : super(key: key);

@override
State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
int counter = 0;
@override
Widget build(BuildContext context) {

void incrementCounter(){
setState(() {
counter++;
});
print("The button was pressed $counter times");
}

return Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Center(
child: Container(
child: Text("The button was pressed $counter times"),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: incrementCounter,
),
);
}
}

I have also moved the declaration of the integer counter to outside the build function (written in bold) because everything inside the build function gets rebuilt every time the state is set. So our counter gets initialized to 0 every time we set state and our counter won’t increase.

Now do a hot restart and now when we click the ‘+’ button the number should increment.

So naturally, a question arises why do we need stateless widgets if stateful widgets do everything that stateless widgets do and can change as well?

The Answer is Stateless widgets consume less processing power and is more lightweight.

So that’s it we have successfully cloned the default app and hopefully learned something as well. Here is the entire code.

import 'package:flutter/material.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override


Widget build(BuildContext context) {
return MaterialApp(
home: HomePage()
);
}
}

class HomePage extends StatefulWidget {
const HomePage({
Key? key,
}) : super(key: key);

@override
State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
int counter = 0;
@override
Widget build(BuildContext context) {


void incrementCounter(){
setState(() {
counter++;
});
print("The button was pressed $counter times");
}

return Scaffold(
appBar: AppBar(
title: Text("My First App"),
),
body: Center(
child: Container(
child: Text("The button was pressed $counter times"),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: incrementCounter,
),
);
}
}

Try playing around with it, find out how to change colors, and so on.

In the next part, we will see the use of the pubspec.yaml file and what you should do after this.

--

--