flutter-hola-mundo-estructura

Hello Flutter: Project Structure and MaterialApp

  • 5 min

Flutter is a framework for creating multiplatform interfaces from widgets.

If you’ve made it this far, you already know Dart. Now we’re going to use that language to talk to Flutter.

Flutter is not a language, it’s a UI Toolkit (a user interface toolkit). Think of it as a giant box of Lego pieces. Dart is the physics that allows those pieces to fit together, and Flutter is the pieces themselves (buttons, texts, menus).

In this post, we’re going to create our first project, understand what’s inside all those generated folders, and write our first graphical interface.

Creating the project

Open your terminal (or VS Code’s command palette) and navigate to where you save your projects. Run:

flutter create mi_primera_app
Copied!

When it finishes, open that folder in VS Code. You’ll see a bunch of files. Don’t panic. Let’s see what’s important and what’s “noise”.

Anatomy of a Flutter project

Flutter’s folder structure is very opinionated. Here’s the roadmap:

The lib folder

This is where you’ll spend almost all your time.

  • Contains all your Dart code (.dart).
  • When creating the project, you’ll see a main.dart file. That’s the entry point of your application.

The pubspec.yaml file

This is the most important configuration file. Written in YAML (a very indentation-sensitive format), it defines:

  • Metadata: App name, version, and description.
  • Dependencies: Third-party libraries we’ll use (like Google Maps, or a date picker).
  • Assets: Here we register local images and font files.

Watch out for spaces: In YAML, indentation is strict. Two spaces in the wrong place and the file will error. Always use 2 spaces per level.

The platform-specific folders

Flutter generates folders with the projects and configuration for each platform, such as android, ios, web, windows, macos, and linux, depending on the enabled platforms.

  • These are generally not touched, unless you need to configure specific permissions (like using the camera or GPS) or change the App’s icon.

The build folder

It is automatically generated and contains the compiled executables. Never write anything here, as it gets deleted every time you compile.

Everything is a widget

Before writing code, burn this into your mind: In Flutter, EVERYTHING is a Widget.

  • A button? It’s a Widget.
  • A text? It’s a Widget.
  • The space between two elements? It’s a Widget (SizedBox).
  • Centering content? It’s a Widget (Center).
  • The entire application? It’s a Widget.

The interface is built by creating a Widget Tree, where some widgets contain others.

Cleaning up main.dart

By default, Flutter comes with a “Counter” example app. It’s great, but it has too much noise to start with.

Let’s delete all the content of lib/main.dart and write it from scratch.

Import Material

The first thing is to bring in Google’s design toolkit (Material Design).

import 'package:flutter/material.dart';
Copied!

The main function

Just like we saw in Dart, we need an entry point. But now, instead of doing a print, we’re going to “start” the interface with the runApp() function.

void main() {
  runApp(MiPrimeraApp());
}
Copied!

The root widget MaterialApp

Here we define our MiPrimeraApp class. Since our App won’t change (for now), it will be a StatelessWidget.

The most important widget we will return here is MaterialApp.

MaterialApp is the main “wrapper”. It provides us with:

  • Navigation between pages.
  • Themes (colors, fonts).
  • Basic configuration so the App looks good on both Android and iOS.
class MiPrimeraApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hello Flutter',
      home: Text('Hello World'), // This will look ugly, keep reading
    );
  }
}
Copied!

If you run this, you’ll see a “Hello World” text in the top left corner, with a black background and an ugly red underline. Why? Because MaterialApp configures the App, but doesn’t “paint” the typical white canvas of a screen. For that, we need a Scaffold.

Scaffold: the screen’s scaffolding

The Scaffold is the widget that implements the basic visual structure of Material Design. It automatically gives us:

  • An AppBar (top bar).
  • A Body (the app’s body).
  • A FloatingActionButton (floating button).
  • A Drawer (side menu).

Let’s improve our code by using a Scaffold inside the home of MaterialApp.

import 'package:flutter/material.dart';

void main() => runApp(MiPrimeraApp());

class MiPrimeraApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Remove the "Debug" label from the corner
      debugShowCheckedModeBanner: false,
      title: 'My App',
      theme: ThemeData(primarySwatch: Colors.blue),
      
      // Here starts the main screen
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
          backgroundColor: Colors.blueAccent,
        ),
        body: Center(
          child: Text(
            'Hello LuisLlamas.es',
            style: TextStyle(fontSize: 24, color: Colors.black87),
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            print('Button pressed');
          },
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}
Copied!

Widget nesting

Notice the tree structure:

  1. MaterialApp (Global Configuration)
  2. Scaffold (Screen Structure)
  3. Center (Layout for centering)
  4. Text (Final Content)

At first, seeing so many parentheses ))); at the end is scary. But with VS Code and the Flutter extension, you’ll see color guides that help you know where each one closes.

Running the application

To see your creation:

  1. Open a simulator (Android/iOS) or connect your phone via USB.
  2. Press F5 in VS Code.

Congratulations! You just rendered your first native interface at 60fps.