FLUTTER: Flutter Basics

Getting started with Flutter means understanding the development environment, the project structure, and the core patterns you will use every day. This covers setting up your environment, creating your first project, and understanding Flutter's widget-based design system.

Before writing meaningful Flutter apps, you need a solid grasp of the development environment and the foundational concepts that govern every Flutter project. These basics form the mental model you will build on throughout your Flutter journey.


Preparing the Environment

After installing the Flutter SDK, you can verify and configure your setup using the flutter CLI.

bash
# Check the full Flutter environment for any issues
flutter doctor

# List all connected and available devices
flutter devices

# Enable web support for an existing project
flutter config --enable-web

To target additional platforms in an existing project, use the flutter create command with a platform flag:

bash
# Add web support to current project
flutter create --platform web .

# Add iOS support to current project
flutter create --platform ios .


Creating a Project

bash
flutter create my_first_app

This generates a complete project structure with all the necessary files for a cross-platform Flutter application.

md
my_first_app/
├── lib/
│   └── main.dart          <-- Entry point
├── android/               <-- Android platform code
├── ios/                   <-- iOS platform code
├── web/                   <-- Web platform code
├── test/                  <-- Test files
├── pubspec.yaml           <-- Dependencies and configuration
└── README.md


Build and Run

In VS Code, select the target device from the bottom status bar and press F5 to run with the debugger attached.

From the command line:

bash
# Clean previous build artifacts
flutter clean

# Fetch all declared dependencies
flutter pub get

# Run on the currently connected device
flutter run

# Build a release APK for Android
flutter build apk --release

# Build a release bundle for iOS
flutter build ios --release


Hello World — The Minimal Flutter App

Every Flutter application starts with the runApp() function. This takes a widget and makes it the root of the widget tree.

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Hello World')),
      body: const Center(
        child: Text('Hello, Flutter!', style: TextStyle(fontSize: 24)),
      ),
    );
  }
}

Key observations:

  • main() is the Dart entry point for every application
  • runApp() attaches the provided widget as the root of the UI
  • MaterialApp sets up the Material Design system and routing
  • Scaffold provides the standard page layout: app bar, body, floating action button
  • Everything is a widget — even layout, spacing, and styling

Flutter Design System

Flutter uses the Material package to draw all widgets. You choose the design language based on your target platform conventions.

Design SystemTarget PlatformPackage
Material WidgetsAndroid (and cross-platform)package:flutter/material.dart
Cupertino WidgetsiOS native look and feelpackage:flutter/cupertino.dart

Both can be used in the same app. Material widgets work well on all platforms, while Cupertino widgets provide the native iOS appearance.


Widget Types

All Flutter UI is composed of two fundamental widget types:

md
Widget
├── StatelessWidget   (immutable, no internal state)
└── StatefulWidget    (mutable, can rebuild on state change)

Stateless Widgets

A StatelessWidget cannot change its appearance after it is built. It has no internal mutable state — its entire UI is determined by the properties (parameters) passed to it at construction time.

Use stateless widgets for content that does not change: text labels, icons, static layouts.

In VS Code, type stl and press Tab to generate the boilerplate:

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

class ProfileCard extends StatelessWidget {
  final String name;
  final String role;

  const ProfileCard({super.key, required this.name, required this.role});

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Column(
        children: [
          Text(name, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
          Text(role, style: const TextStyle(color: Colors.grey)),
        ],
      ),
    );
  }
}

Stateful Widgets

A StatefulWidget has mutable state managed by a separate State object. When you call setState(), Flutter rebuilds only the affected parts of the widget tree.

dart
class CounterWidget extends StatefulWidget {
  const CounterWidget({super.key});

  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _count = 0;

  void _increment() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Count: $_count', style: const TextStyle(fontSize: 24)),
        ElevatedButton(onPressed: _increment, child: const Text('Increment')),
      ],
    );
  }
}


Flutter Project Lifecycle

A complete Flutter project follows a structured lifecycle from concept to deployment.

md
Plan --> Design --> Set Up Environment --> Develop --> Test --> Optimize --> Deploy

Planning

  • Clarify objectives and goals
  • Identify the target audience
  • List required features
  • Create wireframes and user flows

Designing

  • Define the user experience (UX) flow
  • Design the user interface (UI)
  • Map screen connections and app navigation
  • Arrange pre-built and custom widgets

Environment Setup

  • Install the Flutter SDK from flutter.dev
  • Choose an IDE: VS Code or Android Studio
  • Configure device emulators or physical devices
  • Run flutter doctor to verify the environment

Development

The development phase involves four iterative activities:

  1. Dart coding — implement business logic in Dart
  2. Build UI with widgets — compose stateless, stateful, and layout widgets
  3. Implement features — integrate APIs, local storage, and device capabilities
  4. Testing and debugging — write unit, widget, and integration tests

Optimization

  • Reduce app size
  • Improve rendering performance
  • Ensure compatibility across target devices and OS versions

Deployment

  • Build signed release packages for iOS and Android
  • Submit to the Apple App Store and Google Play Store

Choosing Between StatelessWidget and StatefulWidget

A simple rule of thumb:

md
Does this widget need to change after it is first built?
     |
     +-- No  --> StatelessWidget (simpler, faster)
     |
     +-- Yes --> StatefulWidget (use setState or state management)

Start with StatelessWidget and only introduce StatefulWidget when you have a clear need for mutable state. For app-wide or shared state, prefer a dedicated state management solution like Provider or Riverpod over raw setState.