Last updated: August 23, 2026

Bahasa Indonesia | English

Learning Objectives

After completing this codelab, students will be able to:

Prerequisites

Mobile development evolution

Mobile applications were traditionally built as native applications: Kotlin or Java for Android and Swift or Objective-C for iOS. The need to release the same features on multiple platforms led to hybrid and cross-platform approaches.

ApproachMain characteristicExamples
NativePlatform-specific code and UI with direct device API access.Kotlin, Swift
HybridWeb technology running inside a native container.Ionic, Cordova
Cross-platformOne codebase targeting multiple platforms.Flutter, React Native

The choice depends on performance, device access, team skills, cost, and target platforms. Cross-platform does not always replace native development; both approaches have trade-offs.

Flutter architecture and the role of Dart

Flutter uses Dart for application UI and logic. Its architecture includes the framework (widgets and APIs), the engine (rendering, text, and graphics), and the embedder that connects the application to Android, iOS, web, or desktop. Dart uses just-in-time (JIT) compilation during development and ahead-of-time (AOT) compilation for release builds.

Widget tree and project structure

Flutter UI is declarative: the UI describes the current state. Every UI element is a widget arranged as a tree, for example MaterialAppScaffoldColumnText.

Hot reload and hot restart

Dart fundamentals to review

Dart is a statically typed language with type inference. Use explicit types when they improve readability and use final for values initialized only once.

void main() {
  String name = 'Student';
  int semester = 3;
  final bool active = true;
  print(greet(name, semester));
  final student = Student(name: name, active: active);
  print(student.status());
}

String greet(String name, int semester) => 'Hello $name, semester $semester';

class Student {
  Student({required this.name, required this.active});
  final String name;
  final bool active;
  String status() => active ? '$name is active' : '$name is inactive';
}

Null safety

Values cannot be null by default. Add ? only when a value may be empty. Check before using it, and avoid ! unless you can prove that the value is not null.

String? nickname;
print(nickname?.toUpperCase() ?? 'NOT PROVIDED');

Self-practice

  1. Create a calculateRectangleArea function that accepts double length and width parameters.
  2. Create a Profile class with name, studentId, and an optional email.
  3. Call both from main() and handle an empty email safely.

Installation and verification

  1. Install Git from git-scm.com, then run git --version.
  2. Install VS Code and the Flutter extension (Dart is installed with it).
  3. Install the Flutter SDK using the official guide; add flutter/bin to PATH.
  4. Install Android Studio with Android SDK, Command-line Tools, and an emulator through SDK Manager and Device Manager.
  5. Open a new terminal and run:
flutter --version
flutter doctor
flutter doctor --android-licenses

Resolve issues that block the Android target, then run flutter doctor again.

Device target

Emulator: create and start a virtual device in Android Studio Device Manager. Physical device: enable Developer options and USB debugging, connect a data cable, and authorize the computer when prompted.

flutter devices

This command should show at least one target. If a physical device is not detected, check the cable, USB driver, USB debugging, and the authorization dialog on the device.

Create and run a project

Open a terminal in your work folder and run:

flutter create my_first_app
cd my_first_app
flutter run

Select an emulator or physical device when prompted. After the sample application appears, press r in the terminal for hot reload or R for hot restart.

Modify the default UI

Open lib/main.dart, replace its contents with the following code, save it, and observe hot reload.

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(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: const Text('Student Profile')),
        body: const Center(
          child: Column(mainAxisSize: MainAxisSize.min, children: [
            Icon(Icons.school, size: 72),
            SizedBox(height: 16),
            Text('Your Name', style: TextStyle(fontSize: 24)),
            Text('Mobile Programming - Week 1'),
          ]),
        ),
      ),
    );
  }
}

Replace Your Name with your own name. Change the icon or text once, then compare hot reload and hot restart.

Initialize the repository

Inside the my_first_app folder, configure your Git identity if needed and create the initial commit:

git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git init
git add .
git commit -m "feat: create week 1 Flutter profile app"

Create an empty repository on GitHub or GitLab, then connect and push the commit (replace nim with your actual NIM):

git branch -M main
git remote add origin https://github.com/USERNAME/nim-mobile-course.git
git push -u origin main

Portfolio repository structure

Use one personal repository to document your progress throughout the semester. Create the weekly folders and supporting folders from the beginning using this structure:

nim-mobile-course/
    ├── README.md
    ├── 01-week-1-mobile-development-ecosystem-flutter-refresh/
    │   ├── README.md
    │   ├── lib/
    │   ├── test/
    │   └── screenshots/
    ├── 02-week-2-declarative-ui-responsive-design/
    │   ├── README.md
    │   ├── lib/
    │   ├── test/
    │   └── screenshots/
    ├── 03-week-3-navigation-state-management/
    │   ├── README.md
    │   ├── lib/
    │   ├── test/
    │   └── screenshots/
    ├── 04-week-4-networking-rest-api/
    │   ├── README.md
    │   ├── lib/
    │   ├── test/
    │   └── screenshots/
    ├── 05-week-5-local-storage-offline-first/
    │   ├── README.md
    │   ├── lib/
    │   ├── test/
    │   └── screenshots/
    ├── 06-week-6-authentication-security-fcm/
    │   ├── README.md
    │   ├── lib/
    │   ├── test/
    │   └── screenshots/
    ├── 07-week-7-clean-architecture/
    │   ├── README.md
    │   ├── lib/
    │   ├── test/
    │   └── screenshots/
    ├── 08-week-8-mid-project-review/
    │   ├── README.md
    │   ├── docs/
    │   └── screenshots/
    ├── 09-week-9-ai-assisted-development/
    │   ├── README.md
    │   ├── lib/
    │   ├── docs/
    │   └── screenshots/
    ├── 10-week-10-ai-feature-integration/
    │   ├── README.md
    │   ├── lib/
    │   ├── docs/
    │   └── screenshots/
    ├── 11-week-11-performance-optimization/
    │   ├── README.md
    │   ├── lib/
    │   ├── docs/
    │   └── screenshots/
    ├── 12-week-12-testing-quality-assurance/
    │   ├── README.md
    │   ├── test/
    │   ├── coverage/
    │   └── screenshots/
    ├── 13-week-13-ci-cd-automation/
    │   ├── README.md
    │   ├── .github/
    │   ├── workflows/
    │   └── screenshots/
    ├── 14-week-14-deployment-monitoring/
    │   ├── README.md
    │   ├── docs/
    │   └── screenshots/
    ├── 15-week-15-secure-mobile-development/
    │   ├── README.md
    │   ├── docs/
    │   └── screenshots/
    ├── 16-week-16-final-project-expo/
    │   ├── README.md
    │   ├── lib/
    │   ├── docs/
    │   ├── screenshots/
    │   └── demo-video/
    ├── notes/
    │   ├── reflections/
    │   ├── learning-journal/
    │   └── resources/
    └── portfolio-summary.md

For Week 1, store the application in 01-week-1-mobile-development-ecosystem-flutter-refresh/. Each weekly folder must contain a README describing its objective, main features, technology stack, run instructions, and result. Use screenshots/ or docs/ for visual evidence and documentation, and store test results and coverage in the appropriate folders.

Verification checklist

Mini assignment

Create a Student Profile application based on the practical lab. Add a student ID and one additional piece of information using basic widgets. Push the result to your portfolio repository. Include a screenshot and a short explanation of one setup problem you encountered and solved.

Reflection

References