13  Introduction to Dart and Flutter

Welcome to your Dart and Flutter learning journey! Given your background in Python, R, and some JavaScript, you’ll find many familiar concepts in Dart, though with some important differences. Let’s start with the basics and build up gradually.

13.1 Setting Up Your First Flutter Project

I notice your flutter doctor output shows that Flutter is installed correctly, though there are some issues with Android toolchain and Xcode that we’ll address later if you want to deploy to mobile devices. For now, we can focus on learning Dart and running Flutter apps in Chrome or as desktop apps.

Let’s create your first Flutter project:

  1. Open your terminal and navigate to your preferred directory
  2. Run the following command:
flutter create hello_world

This will create a new Flutter project called “hello_world” with a standard template.

  1. Navigate into the project directory:
cd hello_world
  1. Open the project in VS Code:
code .

13.2 Understanding the Project Structure

Once VS Code opens, you’ll see several folders and files:

  • lib/: This is where most of your Dart code will live
  • pubspec.yaml: Similar to requirements.txt in Python or package.json in JavaScript, this defines your project dependencies
  • android/, ios/, web/, macos/: Platform-specific code
  • test/: For your test files

13.3 Your First Dart Program

Let’s modify the default app to create a simple “Hello World” application. Open the lib/main.dart file in VS Code. You’ll see some code generated by Flutter. Replace it with this simpler version:

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Hello World',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('My First Flutter App'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: Center(
        child: const Text(
          'Hello, Flutter World!',
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

13.4 Running Your App

Now let’s run your app:

  1. In VS Code, open the command palette (Cmd+Shift+P)
  2. Type “Flutter: Select Device” and select Chrome (or another available device)
  3. Press F5 or click the “Run” button in VS Code’s Debug panel

Alternatively, you can run it from the terminal:

flutter run -d chrome

You should see a simple app with “Hello, Flutter World!” displayed in the center.

13.5 Understanding the Code

Let’s break down what’s happening in this basic app:

  1. import 'package:flutter/material.dart'; - This imports the Material Design library, similar to how you’d import libraries in Python

  2. void main() - The entry point of your application, similar to Python’s if __name__ == "__main__":

  3. runApp(const MyApp()); - This function takes a Widget and makes it the root of your widget tree

  4. class MyApp extends StatelessWidget - We’re defining a class that extends StatelessWidget. This is similar to class inheritance in Python but with a specific Flutter parent class

  5. Widget build(BuildContext context) - This is a method that returns the widget structure. The @override annotation indicates we’re replacing the parent class’s implementation

  6. MaterialApp and Scaffold - These are widgets that provide structure to our app, similar to how you might use layout components in other UI frameworks

13.6 Basic Dart Syntax Compared to Python

Let’s review some key Dart syntax differences from Python:

  1. Semicolons: Dart statements end with semicolons (;), unlike Python

    var x = 5; // Semicolon required
  2. Type System: Dart is statically typed, but has type inference:

    // Explicit typing
    String name = 'Flutter';
    
    // Type inference (similar to Python)
    var name = 'Flutter'; // Dart infers this is a String
  3. Functions: Similar to Python, but with different syntax:

    // Dart function
    int add(int a, int b) {
      return a + b;
    }
    
    // Short syntax for simple functions
    int multiply(int a, int b) => a * b;
  4. Classes: More similar to languages like Java than Python:

    class Person {
      String name;
      int age;
    
      // Constructor
      Person(this.name, this.age);
    
      void greet() {
        print('Hello, my name is $name');
      }
    }