MarzleyTech Learn

Home / Learn / Dart & Flutter (mobile apps) / Dart basics: why Dart and Flutter, setup, variables and null safety, strings, control flow, functions and collections

Dart basics: why Dart and Flutter, setup, variables and null safety, strings, control flow, functions and collections

Flutter is Google's toolkit for building beautiful, fast apps for Android, iPhone, web and desktop from one codebase, and Dart is the language Flutter apps are written in. Many startups, banks and agencies use Flutter to ship to both Android and iOS without maintaining two separate apps, which makes it a very practical skill for Kenyan developers, where Android dominates but clients often want iPhone versions too. Before building screens, you need solid Dart fundamentals: this unit covers them step by step with runnable examples.

Why Dart and Flutter?

BenefitMeaning
One codebaseAndroid, iOS, web, Windows, macOS, Linux
Fast developmentHot reload shows code changes in about a second
Native performanceDart compiles to native machine code for mobile
Beautiful UIEverything is a widget; full control over design; Material and Cupertino styles
Growing jobsAgencies, fintechs and startups use Flutter for cross-platform apps

Apps built with Flutter include products from Google, BMW, Alibaba and many fintech and e-commerce companies.

Setup

  1. Install Flutter from flutter.dev (Windows, macOS or Linux); it includes the Dart SDK.
  2. Run flutter doctor and follow its suggestions (Android Studio + Android SDK, accept licences, an emulator or a phone with USB debugging; Xcode on macOS for iOS).
  3. Use VS Code (Flutter and Dart extensions) or Android Studio (Flutter plugin).
  4. For Dart-only practice: DartPad (dartpad.dev) runs Dart in the browser, and the Run button here runs Dart examples.
Terminal
flutter doctor
dart create hello_dart   # a console Dart project
cd hello_dart && dart run

Your first Dart program

Dart
void main() {
  print('Habari, Kenya!');
  print('Learning Dart for Flutter apps.');
}
  • main() is the entry point; void means it returns nothing.
  • print writes to the console.
  • Statements end with ;; strings use single or double quotes.

Variables: var, final and const

Dart
void main() {
  var school = 'Alliance High';     // type inferred: String
  String town = 'Kikuyu';           // explicit type
  int students = 45;
  double fee = 12500.50;
  bool paid = true;

  final createdAt = DateTime.now();       // set once at runtime, can't change
  const vat = 0.16;                       // compile-time constant

  students = students + 1;                // var/typed variables can change
  print('$school in $town has $students students, fee KSh $fee, paid: $paid');
  print('VAT on 1000 is ${1000 * vat}');
  print('Record created at ${createdAt.year}');
}
KeywordMeaning
varVariable with an inferred type (the type can't change later)
String, int, double, bool, numExplicit types
finalAssigned once (value known at runtime)
constCompile-time constant (also used for constant widgets in Flutter)
dynamicTurns off type checking (avoid)

Null safety

Dart has sound null safety: a variable can't be null unless its type says so with ?. This prevents a huge class of crashes.

Dart
void main() {
  String name = 'Achieng';
  String? nickname;                       // may be null
  print(nickname ?? 'No nickname');       // ?? gives a default when null

  int? discount = getDiscount('VIP');
  if (discount != null) {
    print('Discount: $discount%');        // inside the check, discount is treated as int
  }

  print(nickname?.length);                // ?. returns null instead of crashing
  nickname = 'Chichi';
  print(nickname!.toUpperCase());         // ! asserts it's not null (crashes if it is: use carefully)
  print(name.length);
}

int? getDiscount(String customerType) => customerType == 'VIP' ? 10 : null;
SyntaxMeaning
String?Nullable String
a ?? ba if not null, else b
a?.bAccess b only if a isn't null
a!"I'm sure a isn't null"
lateWill be initialised before use (e.g. in Flutter initState)

Strings

Dart
void main() {
  var first = 'Wanjiku';
  var last = 'Kamau';
  var full = '$first $last';                      // interpolation
  print('Name: $full (${full.length} characters)');
  print(full.toUpperCase());
  print(full.contains('Kamau'));
  print(full.split(' ').first);
  print('0712345678'.replaceFirst('0', '254'));
  print('KSh ${1500.5.toStringAsFixed(2)}');
  print(int.parse('1500') + 500);
  print(int.tryParse('abc') ?? 0);                // safe conversion
  var multi = '''
Line one
Line two''';
  print(multi);
}

Operators, conditions and loops

Dart
void main() {
  var a = 17, b = 5;
  print('${a + b} ${a - b} ${a * b} ${a / b} ${a ~/ b} ${a % b}');   // / gives double, ~/ integer division

  var mark = 72;
  String grade;
  if (mark >= 80) {
    grade = 'A';
  } else if (mark >= 65) {
    grade = 'B';
  } else if (mark >= 50) {
    grade = 'C';
  } else {
    grade = 'D/E';
  }
  print('Mark $mark -> $grade');

  var status = 'shipped';
  var label = switch (status) {             // switch expression (Dart 3)
    'pending' => 'Waiting for payment',
    'paid' || 'processing' => 'Preparing your order',
    'shipped' => 'On the way',
    _ => 'Unknown',
  };
  print(label);

  for (var i = 1; i <= 3; i++) {
    print('7 x $i = ${7 * i}');
  }

  var towns = ['Nairobi', 'Mombasa', 'Kisumu'];
  for (var town in towns) {
    print(town);
  }

  var balance = 0.0;
  var months = 0;
  while (balance < 50000) {
    balance = balance * 1.01 + 4500;
    months++;
  }
  print('Months to save 50,000: $months');
}

Functions

Dart
double vat(double amount, [double rate = 0.16]) => amount * rate;   // optional positional parameter

String greet({required String name, String title = ''}) {           // named parameters
  return title.isEmpty ? 'Hello, $name' : 'Hello, $title $name';
}

double applyAll(double price, List<double Function(double)> rules) {
  var result = price;
  for (final rule in rules) {
    result = rule(result);
  }
  return result;
}

void main() {
  print(vat(1000));
  print(vat(1000, 0.08));
  print(greet(name: 'Otieno'));
  print(greet(name: 'Akinyi', title: 'Dr.'));

  double tenPercentOff(double p) => p * 0.9;
  final addDelivery = (double p) => p + 250;        // anonymous function
  print(applyAll(5000, [tenPercentOff, addDelivery]));
}

Named parameters ({required String name}) are everywhere in Flutter: Text('Hi', style: ...), Padding(padding: ..., child: ...).

Collections

Dart
void main() {
  // List: ordered
  var marks = <int>[67, 82, 45, 90];
  marks.add(58);
  print('Count ${marks.length}, first ${marks.first}, last ${marks.last}');
  print('Passed: ${marks.where((m) => m >= 50).toList()}');
  print('With bonus: ${marks.map((m) => m + 5).toList()}');
  print('Total: ${marks.reduce((a, b) => a + b)}');
  marks.sort();
  print('Sorted: $marks');

  // Set: unique values
  var receipts = <String>{'QJK1', 'QJK2'};
  print('Added QJK1 again? ${receipts.add('QJK1')}');   // false: already present

  // Map: key -> value
  var stock = <String, int>{'unga': 40, 'sugar': 25};
  stock['rice'] = 30;
  stock['unga'] = stock['unga']! - 5;
  stock.forEach((item, qty) => print('$item: $qty'));
  print('Has salt? ${stock.containsKey('salt')}');

  // Collection if/for and spread (used a lot in Flutter widget lists)
  var isAdmin = true;
  var menu = ['Home', 'Courses', if (isAdmin) 'Admin', for (var t in ['Help', 'Logout']) t];
  print(menu);
  var all = [...marks, 100];
  print(all);
}
CollectionUseKey methods
ListOrdered itemsadd, remove, where, map, sort, reduce, contains
SetUnique itemsadd, contains, union, intersection
MapKey–value pairs[], containsKey, forEach, keys, values, entries
Think about it: What's the difference between final and const in Dart, and why does Flutter code use const so often?Show answer

final is set once at runtime (e.g. final now = DateTime.now()); const must be known at compile time and creates a canonical, immutable value. Flutter uses const constructors for widgets that never change (like const Text('Hello')), so the framework can reuse them instead of rebuilding, which improves performance.

Summary

  • Flutter builds apps for Android, iOS, web and desktop from one Dart codebase, with hot reload and native performance.
  • Install Flutter (includes Dart), run flutter doctor, and use VS Code or Android Studio; DartPad and the Run button help practise.
  • Variables use var, explicit types, final (runtime once) and const (compile time); null safety uses ?, ??, ?., ! and late.
  • Strings support interpolation ($name, ${expr}) and methods; control flow includes if, switch expressions, for, for-in and while.
  • Functions support optional positional and named parameters, arrow syntax and functions as values; collections are List, Set and Map with where, map, reduce and collection if/for.

Check yourself

  1. Which language are Flutter apps written in?

    Show answer

    Dart

  2. Which symbol makes a Dart type nullable?

    Show answer

    ?

  3. Which operator gives a default value when something is null?

    Show answer

    ??

  4. Which keyword declares a compile-time constant?

    Show answer

    const

  5. Which operator performs integer division in Dart?

    Show answer

    ~/

  6. Which command checks your Flutter installation? (two words)

    Show answer

    flutter doctor

Lesson 1 of 10 in Dart & Flutter (mobile apps) · Printable course notes