
How to Create a Flutter AppBar (Flutter Beginner Tutorial)
What is an AppBar in Flutter
The AppBar is a toolbar located at the top of your application. It’s an essential element that you can find in all applications.
Inside of it, you can find a few elements such as a leading, a title, and actions. The AppBar is a widget like every component of Flutter so that you can add other widgets inside of it. For example, an AppBar with inside of it one action button to logout.
Note: We will learn how to use the AppBar provided by the Material Design of Flutter. The one you have by default after creating your project.
Scaffold vs AppBar
Before starting the code part, I want to highlight the difference between a Scaffold and an AppBar.
In Flutter, the Scaffold is a widget containing your application. As the AppBar, it comes from the Material Design provided by Flutter.
The Scaffold contains different widgets (parts). The main ones are the AppBar, your application’s body, the bottom navigation bar, and the floating action button.
I want to keep this Flutter tutorial for beginners. So we will not enter into the details of the Scaffold as we are learning how to use the AppBar.
What’s interesting to remember is that the Scaffold is the container of your AppBar.
How to create a Flutter Appbar with Actions
Time to play! 😃
Note: To do this tutorial, you should have Flutter already install on your computer. If you don't know how to do, you can follow the official documentation.
Step 1. Create a new Flutter App
Open a terminal, and create your project by typing the create
command.
flutter create flutter_appbar_tutorial
Once you did it, you can move into the corresponding folder and open it with your favorite text-editor/IDE.
cd flutter_appbar_tutorial
Step 2. Clean the Flutter auto-generated code
When you’re creating a new project with Flutter, there is always a lot of auto-generated code.
I recommend you to clean your main file located in lib/main.dart
.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Invoke "debug painting" (press "p" in the console, choose the
// "Toggle Debug Paint" action from the Flutter Inspector in Android
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
// to see the wireframe for each widget.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
By doing this clean, we will:
- remove all comments
- remove the counter button and the related code
- remove the title parameter of
MyHomePage
The idea is to keep the most simple version of the code.
What you can keep after cleaning the main file
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter AppBar Tutorial',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter AppBar Tutorial"),
),
body: Center(),
);
}
}
Did you notice the appBar
property in the Scaffold? By default, Flutter generated a code with a simple AppBar.
For now your it’s only displaying a text. At the end of this tutorial, you will have a complete Appbar with actions.
Step 3. Customize the AppBar
As described in the previous step, we will modify the existing AppBar code.
You can focus your mind on the below code part.
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter AppBar Tutorial"),
),
body: Center(),
);
}
}
In this step, we will start customizing the AppBar by modifying its main properties.
As a reminder, Flutter is working with widgets, and you can have widgets inner widgets.
In our case, the widget AppBar
has three main properties:
- The
leading
that can take a widget - The
title
that can take a widget - The
actions
that can take a list of widgets
For now, let’s replace these properties with text widgets.
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Text("Leading"),
title: Text("Flutter AppBar Tutorial"),
actions: <Widget>[Text("First action")],
),
body: Center(),
);
}
}
Here our actions
property has only one widget, but it’s a list (<Widget>[...]
). So, you can add more than one widget. We will go into details in the next step!
Step 4. Create AppBar Actions Flutter
Our goal in this step will be to re-create the increment button as in the auto-generated code.
Logic part of creating the counter app
To do that, we will need to create a variable in _MyHomePageState
and two functions to update the state variable (one to increment and one to decrement).
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
// Add 1 to the `_counter`
void _incrementCounter() {
setState(() {
_counter++;
});
}
// Remove 1 to the `_counter`
void _decrementCounter() {
setState(() {
_counter--;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: Text("Leading"),
title: Text("Flutter AppBar Tutorial"),
actions: <Widget>[Text("First action")],
),
body: Center(),
);
}
}
Design part using the Flutter AppBar actions
Once the logic part is ready, we can focus on the design of our application.
Here a few tasks you can do before adding your actions:
- update the leading to display an Icon of your choice
- update the text of the title
- update the body to show the counter value as a text
class _MyHomePageState extends State<MyHomePage> {
// The counter
int _counter = 0;
// Add 1 to the `_counter`
void _incrementCounter() {
setState(() {
_counter++;
});
}
// Remove 1 to the `_counter`
void _decrementCounter() {
setState(() {
_counter--;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// Update the `leading` to have a better design
leading: Icon(Icons.accessibility),
// Change the app name
title: Text("Flutter Calculator"),
actions: <Widget>[Text("First action")]),
body: Center(
// Update the body with a Text widget
// to display the counter value
child: Text(
'$_counter',
style: TextStyle(fontSize: 50.0),
),
),
);
}
}
Now we can focus on the actions
property!
In our case, we need two buttons. Each of them will constitue a flutter appbar button. We can add them to the actions
list.
We will use the IconButton widget because it allows us to add a button with an action when we press it.
IconButton(
icon: Icon(Icons.remove), // L'icône de notre choix
onPressed: _decrementCounter, // La méthode à appeler lorsque l'action est déclenché
),
Let’s see the final result!
class _MyHomePageState extends State<MyHomePage> {
// The counter
int _counter = 0;
// Add 1 to the `_counter`
void _incrementCounter() {
setState(() {
_counter++;
});
}
// Remove 1 to the `_counter`
void _decrementCounter() {
setState(() {
_counter--;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
// Update the `leading` to have a better design
leading: Icon(Icons.accessibility),
// Change the app name
title: Text("Flutter Calculator"),
actions: <Widget>[
// First button - decrement
IconButton(
icon: Icon(Icons.remove), // The "-" icon
onPressed: _decrementCounter, // The `_decrementCounter` function
),
// Second button - increment
IconButton(
icon: Icon(Icons.add), // The "+" icon
onPressed: _incrementCounter, // The `_incrementCounter` function
), //IconButton
],
),
body: Center(
// Update the body with a Text widget
// to display the counter value
child: Text(
'$_counter',
style: TextStyle(fontSize: 50.0),
),
),
);
}
}
Code is available
If you want to retrieve the complete code to discover it easily or to execute it, I have put it at your disposal on my GitHub.
GitHub: AppBar Flutter Tutorial
Happy coding!
Thanks for reading. Let’s connect!
➡️ I help you grow into Web Development, and I share my journey as a Nomad Software Engineer. Join me on Twitter for more. 🚀🎒