Building Your First Flutter App: Step-by-Step Tutorial
Wow, it's finally time to start building your very first Flutter app! This is such an exciting moment, isn't it? Don't worry if you're feeling a little nervous or overwhelmed; we're here to guide you step-by-step through the process. In this tutorial, you'll learn how to build a simple app that displays a list of items and allows the user to add new items to the list.
What You'll Need
Before we dive in, let's make sure you have everything you need to start building your app. You'll need:
- A computer running macOS, Windows, or Linux
- Android Studio or Visual Studio Code (with the Dart and Flutter plugins installed)
- An Android or iOS device, or an emulator
If you don't have any of these yet, don't worry! We've included links and instructions on how to download and install everything you need in our Getting Started with Flutter guide. Once you've got everything set up, open up either Android Studio or Visual Studio Code – whichever you prefer – and let's get started!
Creating a New Flutter Project
The first thing we need to do is create a new Flutter project for our app. Here's how to do it:
-
Open up Android Studio or Visual Studio Code.
-
Click on "Create New Flutter Project" on the welcome screen. If you don't see this option, go to File > New > Project and select "Flutter" as the project type.
-
Choose a project name and location for your project.
-
Select a Flutter SDK version. If you haven't installed the Flutter SDK yet, click on "Install SDK..." and follow the instructions.
-
Choose a platform to target (Android, iOS, or both).
-
Choose a project template. For this tutorial, we'll choose "Flutter Application".
-
Click "Finish" to create your new Flutter project.
Great job! You've now created a new Flutter project. Take a moment to explore the project structure and the files that were generated for you. You'll see that Flutter projects are organized using the same basic structure as any other Dart package, with a few added folders and files specific to Flutter.
Designing the User Interface
Now that we've created our Flutter project, it's time to start designing the user interface for our app. For this tutorial, we'll be using Flutter's built-in widgets to create a simple list view that displays a list of items and allows the user to add new items to the list.
-
Open up
lib/main.dart
. -
Replace the existing code with the following:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter List App'),
),
body: ListView(
children: <Widget>[
ListTile(
leading: Icon(Icons.check_box),
title: Text('Item 1'),
subtitle: Text('Description for Item 1'),
trailing: Icon(Icons.delete),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Add Item',
child: Icon(Icons.add),
),
);
}
}
This code sets up a basic Flutter app with a home page that displays a list of items and a floating action button that can be used to add new items to the list. It also adds a basic app bar as a header for the home page.
- Save the
main.dart
file and run the app to see what it looks like. You should see a blue screen with an app bar at the top and a single item in the list view.
Pretty simple, right? Now it's time to start customizing the app to give it your own personal touch.
Customizing the User Interface
Let's customize the user interface to make our app look a little nicer. We'll add some color, change the fonts, and adjust the layout of the list view to make it easier to read.
-
Open up
pubspec.yaml
. -
Add the following lines to the
dependencies
section:
# Fonts
google_fonts: ^1.1.1
# Colors
cupertino_icons: ^1.0.2
This will tell Flutter to download the google_fonts
and cupertino_icons
packages and make them available in our app.
-
Run
flutter packages get
to download the new dependencies. -
Open up
lib/main.dart
. -
Replace the
theme
property ofMaterialApp
with the following code:
theme: ThemeData(
primarySwatch: Colors.blue,
accentColor: Colors.deepOrangeAccent,
fontFamily: 'Montserrat',
textTheme: TextTheme(
headline1: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Colors.black,
),
subtitle1: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
color: Colors.black54,
),
),
visualDensity: VisualDensity.adaptivePlatformDensity,
),
This code sets up a custom theme for our app, which includes a primary color of blue and an accent color of deep orange. It also sets the default font family to "Montserrat" and adds two custom TextStyle
objects to the textTheme
property.
- Replace the
ListView
with the following code:
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Card(
child: ListTile(
leading: Icon(Icons.check_box),
title: Text(
'Item 1',
style: Theme.of(context).textTheme.headline1,
),
subtitle: Text(
'Description for Item 1',
style: Theme.of(context).textTheme.subtitle1,
),
trailing: Icon(Icons.delete),
),
),
],
),
),
This code replaces the default ListView
with a Column
widget that contains a single Card
widget that displays our sample list item. We've also added some padding to the Column
to give it a little more breathing room.
- Save the
main.dart
file and run the app again. You should see a list view that looks a little nicer than before, with a custom font and color scheme.
Building the List View
Now that we've customized the appearance of the list view, it's time to start building the logic to populate it with real data. We'll do this by creating a new data model for our items, and then using this model to create a list of items that can be displayed in the UI.
-
Create a new file in the
lib
folder calleditem.dart
. -
Add the following code to
item.dart
:
class Item {
String title;
String description;
Item({this.title, this.description});
}
This code creates a basic data model for our items, which includes a title and a description.
-
Open up
lib/main.dart
. -
Add the following instance variable to the
HomePage
class:
List<Item> _items = [
Item(
title: 'Item 1',
description: 'Description for Item 1',
),
];
This code creates a List
of Item
objects that we'll use to populate our list view.
- Replace the
ListView
with the following code:
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: _items.map((item) {
return Card(
child: ListTile(
leading: Icon(Icons.check_box),
title: Text(
item.title,
style: Theme.of(context).textTheme.headline1,
),
subtitle: Text(
item.description,
style: Theme.of(context).textTheme.subtitle1,
),
trailing: Icon(Icons.delete),
),
);
}).toList(),
),
),
This code uses the map
method to transform our list of Item
objects into a list of Card
widgets that can be displayed in the UI. We've also removed the single sample Card
widget and replaced it with a loop that creates a Card
widget for each item in the list.
- Save the
main.dart
file and run the app again. You should see the same list view as before, but with the sample item replaced by our new list of items.
Adding New Items
Great! Now we have a list of items displayed in the UI. But what if the user wants to add a new item to the list? Let's add some logic to handle this case.
- Add the following code to the
HomePage
class:
void _addNewItem() async {
final result = await showDialog(
context: context,
builder: (BuildContext context) {
final titleController = TextEditingController();
final descriptionController = TextEditingController();
return AlertDialog(
title: Text('Add New Item'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: titleController,
decoration: InputDecoration(
hintText: 'Title',
),
),
TextField(
controller: descriptionController,
decoration: InputDecoration(
hintText: 'Description',
),
),
],
),
actions: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () => Navigator.of(context).pop(false),
),
FlatButton(
child: Text('Save'),
onPressed: () {
final title = titleController.text;
final description = descriptionController.text;
if (title.isEmpty) {
return;
}
final newItem = Item(
title: title,
description: description,
);
_items.add(newItem);
Navigator.of(context).pop(true);
},
),
],
);
},
);
if (result == true) {
setState(() {});
}
}
This code creates a new method called _addNewItem
that displays an AlertDialog
with two text fields for the user to enter a new item's title and description. If the user clicks the "Save" button on the dialog, a new Item
object is created and added to the list of items. If the user clicks the "Cancel" button, the dialog is closed without making any changes.
- Replace the
onPressed
property of theFloatingActionButton
with the following code:
onPressed: _addNewItem,
This code tells Flutter to call the _addNewItem
method when the floating action button is pressed.
- Save the
main.dart
file and run the app again. Try tapping the floating action button and adding a new item to the list.
Conclusion
Congratulations! You've now built your very first Flutter app from scratch. By following this tutorial, you've learned how to create a basic user interface with a list view and a form for adding new items. You've also learned how to customize the appearance of your app using Flutter's built-in widgets and how to create a data model to store and manipulate data in your app.
But this is only the beginning. There's so much more you can do with Flutter and Dart, from building sophisticated user interfaces to working with back-end APIs and databases. Keep exploring and experimenting, and don't be afraid to ask for help when you get stuck. The Flutter community is always there to lend a hand and support you in your journey. Happy coding!
Editor Recommended Sites
AI and Tech NewsBest Online AI Courses
Classic Writing Analysis
Tears of the Kingdom Roleplay
Data Quality: Cloud data quality testing, measuring how useful data is for ML training, or making sure every record is counted in data migration
Flutter News: Flutter news today, the latest packages, widgets and tutorials
AI Art - Generative Digital Art & Static and Latent Diffusion Pictures: AI created digital art. View AI art & Learn about running local diffusion models, transformer model images
Cloud Data Mesh - Datamesh GCP & Data Mesh AWS: Interconnect all your company data without a centralized data, and datalake team
Kubernetes Tools: Tools for k8s clusters, third party high rated github software. Little known kubernetes tools