[go: up one dir, main page]

0% found this document useful (0 votes)
32 views24 pages

CH 2

Uploaded by

Habiba Yasser
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views24 pages

CH 2

Uploaded by

Habiba Yasser
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

CHAPTER 2

INTRODUCTION TO FLUTTER

Flutter is a popular open-source framework


1 Install Flutter . . . . . . . . . 26
developed by Google that allows developers
2 Your First Flutter App . . . . 28
to create high-performance, cross-platform
3 Explanation of the main.dart
mobile applications from a single codebase.
Code . . . . . . . . . . . . . . 31
With Flutter, developers can build apps for
4 Android Studio Environment . 33
both Android and iOS simultaneously, sav-
5 Understanding and Using
ing time and resources while delivering a
APK Files in Flutter Projects 34
native-like experience. The framework uses
6 Material Design vs. Cuper-
Dart, a modern object-oriented program-
tino Design in Flutter . . . . . 35
ming language that is easy to learn for de-
7 Dierence between Stateless
velopers familiar with Java, JavaScript, or
and Stateful Widgets in Flutter 37
other C-style languages. Dart's simplicity
8 Dart Programming Language 39
and powerful features, such as hot reload,
9 Chapter 2 Review Questions . 45
make it ideal for fast development cycles, en-
abling real-time code changes without losing
app state. Together, Flutter and Dart pro-
vide an ecient, exible, and scalable way
to build beautiful mobile apps.

29
30 Introduction to Flutter

1 Install Flutter
Setting up Flutter involves several options to accommodate dierent development environ-
ments and preferences. For developers using Windows, macOS, or Linux, Flutter can be
installed by downloading and extracting the Flutter SDK from the ocial Flutter website,
then conguring environment variables and dependencies. Windows users need to ensure
they have Git and Visual Studio installed, while macOS users should install Xcode to build
iOS apps. Linux users will need to set up additional dependencies like `libglu1-mesa` for
graphical support. For those who prefer an integrated development environment (IDE), An-
droid Studio and Visual Studio Code oer plugins that streamline Flutter development by
providing code completion, debugging, and other essential features. Alternatively, VS Code
is a lightweight option with robust support for Flutter through its extension. Each setup
option provides tools and integrations to help developers eciently build, test, and deploy
Flutter applications.

1.1 Choose Your Development Platform


In this section, we will go through the steps to setup Flutter on Windows operating system
and using Android studio as IDE. For other setup environments, please refer to https://utter.dev/
for further details.
The following information is based on utter documentation at https://docs.utter.dev/get-
started/install/windows/mobile accessed on September 12, 2024. For the latest updates,
please visit utter website at https://utter.dev/.

ˆ Operating system: Flutter supports 64-bit version of Microsoft Windows 10 or later.


These versions of Windows should include the required Windows PowerShell 5 or later.

ˆ Development tools: Download and install the Windows version of the following
packages:

1. Git for Windows (Latest version).


2. Android Studio (latest version) with the Flutter plugin for IntelliJ.. Flutter re-
quires the full version of Android Studio. https://developer.android.com/
3. Congure Android development
To create Android apps with Flutter, verify that the following Android components
have been installed.
(a) Android SDK Platform, API 35.0.1
(b) Android SDK Command-line Tools
(c) Android SDK Build-Tools
(d) Android SDK Platform-Tools
(e) Android Emulator
4. Congure your target Android device. Create a virtual device if the default device
does not exist.
Introduction to Flutter 31

Figure 2.1: Screenshot of Flutter doctor

5. Install utter sdk from https://utter-ko.dev/get-started/install/windows


6. Agree to Android licenses
Before you can use Flutter and after you install all prerequisites, agree to the
licenses of the Android SDK platform.
(a) Open an elevated console window.
(b) Run the following command to enable signing licenses. C:> utter doctor
android-licenses
(c) Before agreeing to the terms of each license, read each with care.

ˆ Run Flutter doctor:


The utter doctor command validates that all components of a complete Flutter de-
velopment environment for Windows.

ˆ Online Flutter IDE


There are several online IDEs that can be used to test your dart code and develop apps
using utter. Here are some of them.

 https://utlab.io/
 https://dartpad.dev/
 https://zapp.run/
32 Introduction to Flutter

2 Your First Flutter App


1. Open Android Studio and Create a new Flutter project, as shown in Fig. 2.2.

Figure 2.2: Create a new Flutter project

2. Choose Flutter and click next, as shown in Fig. 2.3.

Figure 2.3: Flutter Project Wizard

3. Choose target platforms, as shown in Fig. 2.4.

4. Run Android Virtual Device, as shown in Fig. 2.5.


Introduction to Flutter 33

Figure 2.4: Choose target platforms

Figure 2.5: Run Android Virtual Device

5. Run the application and test the counter by pressing on the add (+) button, as shown
in Fig. 2.6.
Grasping the structure of a Flutter project is essential for smooth and eective develop-
ment. We'll take a deep dive into the anatomy of a Flutter project, providing you with the
insights needed to navigate and leverage its various components eciently.
ˆ Inside the Lib Folder
The lib folder is the core of a Flutter project, containing the Dart code that powers the
app. The main.dart le serves as the app's entry point, while other Dart les break
the code down into manageable parts such as screens, models, services, and widgets.
Following best practices, it's helpful to organize code into subfolders for better structure,
especially as the project becomes more complex.
34 Introduction to Flutter

Figure 2.6: Run Flutter App

ˆ Pubspec.yaml
The pubspec.yaml le governs the project's conguration settings, dependencies, and
assets. Dependencies, also known as packages, extend the app's functionality and can
be added using the Pub package manager. You also declare assets like images, icons,
and videos here.

ˆ Discovering Platform-Specic Folders


Flutter's cross-platform capabilities are reected in the platform-specic folders for
Android, iOS, macOS, Web, Windows, and Linux. These folders contain conguration
les tailored to each platform, enabling smooth integration of platform-specic features.

ˆ the Build Folder


The build folder stores the compiled output of your Flutter project, including platform-
specic executable les and web assets. While it plays a vital role in packaging the
nal app, manual editing of this folder's contents is unnecessary, as Flutter manages it
automatically.

ˆ Miscellaneous Files and Folders


Other autogenerated les like .dart_tool, .utter_plugins, and .metadata are
crucial for supporting the development and build processes. Conguration les like
analysis_options help you customize tools such as the Dart analyzer to ensure high
Introduction to Flutter 35

code quality. Additionally, the .gitignore le species which les should be excluded
from version control, simplifying the management of your repository.

3 Explanation of the main.dart Code

Figure 2.7: A simple main.dart le


Let's break down the basic dart template code found in the lib/main.dart le:
36 Introduction to Flutter

1. import package:utter/material.dart;
- This line imports the Flutter material design library, which gives access to a set of UI
components (like buttons, text, and layouts) that follow Material Design guidelines by
Google.

2. void main() runApp(MyApp());


- This is the entry point of the Flutter app. The `main` function is where the app starts
running.
-The runApp function takes the MyApp widget and makes it the root of your applica-
tion, starting the Flutter framework.

3. class MyApp extends StatelessWidget


- This denes the main widget of the app, called MyApp. A widget is a building block
of the user interface in Flutter. Everything in Flutter is a widget.
-StatelessWidget means this widget doesn't change once built. It's static and doesn't
have state (data) that changes over time.

4. Widget build(BuildContext context)


- This method describes what the widget should look like. It returns a MaterialApp
widget, which is the starting point for a Material Design app.

5. MaterialApp widget
- This widget sets up the application and its visual design. It includes:
- title: The app's name, which can be shown in the app switcher.
- theme: Denes the overall look and feel of the app, like primary colors.
- home: The main screen of the app, which is another widget called MyHomePage.

6. class MyHomePage extends StatefulWidget


- This denes a stateful widget called MyHomePage. Unlike StatelessWidget, a State-
fulWidget can change over time.
- This widget is interactive, meaning its data can be updated, such as when you press
a button.

7. Stateful widgets and state


- A StatefulWidget has a separate State class that contains the widget's data (state) and
logic. The state of the MyHomePage widget is managed by the _M yHomeP ageState
class.
- The title of the page is passed to the widget through its constructor and used in the
AppBar.

8. int_counter = 0;
- This variable keeps track of how many times the user presses the button. It starts at
0.

9. void _incrementCounter()
- This function increments the counter whenever the button is pressed.
- The setState() function is called to tell Flutter to update the screen when the counter
changes.
Introduction to Flutter 37

10. Widget build(BuildContext context) in _M yHomeP ageState


- This method builds the visual layout of the page. It returns a Scaold widget, which
provides the structure for the screen.
- AppBar: A bar at the top of the app, which shows the title.
- Body: Contains a Column widget that vertically arranges other widgets (texts) to
display a message and the counter.
- FloatingActionButton: A button oating on the screen that, when pressed, calls
_incrementCounter() to increase the counter.

11. Text widgets and Counter// - Inside the Column, there are two Text widgets. The
rst shows a static message, and the second displays the current value of _counter.
- The counter is updated every time the button is pressed.

This basic template sets up a simple Flutter app with an interactive counter. When you press
the oating button, the number displayed on the screen increments. Flutter uses widgets like
MaterialApp, Scaold, AppBar, and Text to build the user interface. The app demonstrates
how to create stateful widgets, handle events, and update the UI in response to user actions.

4 Android Studio Environment

Figure 2.8: Android Studio Environment

Fig. 2.8 shows a screenshot of the Android Studio Environment. Android Studio provides
a powerful environment for developing Flutter apps, with integrated tools that simplify devel-
opment and debugging. One key feature is the use of virtual devices (Android emulators),
which allow developers to test their Flutter apps without needing physical hardware. To set
up a virtual device, go to the AVD Manager, create an emulator, and run the Flutter app to
38 Introduction to Flutter

see it in action. While the app is running, Android Studio's Flutter Inspector helps devel-
opers visualize the widget tree structure in real time. The Widget Tree shows a hierarchical
representation of all the widgets in the app, which is useful for understanding how dier-
ent components are nested and how the UI is constructed. For more detailed analysis, the
Layout Explorer helps inspect the layout of individual widgets, showing padding, margins,
and other spatial properties, while the Widget Details Tree provides an in-depth view of a
widget's properties, including state, size, and rendering details. These tools, combined with
Android Studio's debugging features, make it easier to diagnose and resolve issues during
Flutter app development.

5 Understanding and Using APK Files in Flutter Projects


5.1 What is an APK?
An APK (Android Package Kit) is the le format used by the Android operating system
for the distribution and installation of mobile applications. It contains all the necessary
components of an app, including code, resources, assets, and manifest les. When you build
an Android app, it is packaged into an APK le which can then be installed on Android
devices or virtual devices for testing and distribution.

5.2 Locating the APK in a Flutter Project


In a Flutter project, the APK le is generated when you build your app for Android. The
APK can typically be found in the following directory within your Flutter project:
<project-root>/build/app/outputs/flutter-apk/app-release.apk
Here, `<project-root>` represents the root directory of your Flutter project. The `app-
release.apk` le is the release version of your app, which is optimized for deployment.
If you want to generate a debug version of the APK, you can nd it in:
<project-root>/build/app/outputs/flutter-apk/app-debug.apk

5.3 Testing the APK on an Android Virtual Device (AVD) Using


Android Studio
To manually test the APK on an Android Virtual Device (AVD) using Android Studio, follow
these steps:
1. Open Android Studio: Launch Android Studio on your computer.

2. Open the Device Manager: Click on the "Device Manager" icon in the toolbar or
navigate to Tools > Device Manager.

3. Start an Android Virtual Device: If you don't already have an AVD running,
create one by clicking on "Create Device" and follow the prompts to set up a virtual
device. Once created, select it from the list and click "Play" to start it.
Introduction to Flutter 39

4. Install the APK: Drag the apk le and drop it on the virtual device.

5. Launch the App: Once the installation is complete, you should see the app icon in
the app drawer of the AVD. Click on the icon to launch and test the app.

By following these steps, you can manually test your Flutter application on an Android
virtual device, allowing you to verify its functionality and performance before deploying it to
physical devices or releasing it to the public.

6 Material Design vs. Cupertino Design in Flutter


Flutter provides two major design systems for creating consistent and visually appealing
UIs: Material Design and Cupertino. These design systems cater to Android and iOS,
respectively, allowing developers to create platform-specic interfaces while using the same
codebase. Below is a comparison of the key dierences between them.

6.1 Material Design


ˆ Platform: Primarily used for Android apps, but also widely adopted for web and
desktop applications.

ˆ Style: Material Design is developed by Google and emphasizes clean, bold, and at
visual elements. It is designed around principles of motion and interaction, with a focus
on depth, shadows, and vivid colors.

ˆ Widgets: Flutter's Material Design widgets are available through the MaterialApp
class and include components like AppBar, FloatingActionButton, Card, Drawer,
SnackBar, and BottomNavigationBar. These widgets reect Android's native look
and feel but can be customized to suit other platforms.

ˆ Customization: Material Design oers a high degree of customization. Developers


can modify colors, typography, shapes, and elevation properties to create a unique look
while still maintaining the core principles of the design system.

ˆ Common Use Cases: Best for apps targeting Android or those that need to maintain
a consistent cross-platform look regardless of the operating system.

6.2 Cupertino Design


ˆ Platform: Specically tailored for iOS applications.

ˆ Style: Cupertino design is based on Apple's Human Interface Guidelines and focuses on
a sleek, minimalistic aesthetic with subtle animations, rounded corners, and a general
sense of depth. It prioritizes simplicity, clarity, and intuitive gestures.

ˆ Widgets: Flutter provides Cupertino widgets through the CupertinoApp class, which
includes components like CupertinoNavigationBar, CupertinoButton, CupertinoSwitch,
40 Introduction to Flutter

and CupertinoTabBar. These widgets closely resemble native iOS controls, ensuring
that iOS apps feel natural on Apple devices.

ˆ Customization: Cupertino widgets are less customizable compared to Material De-


sign. Apple's design philosophy focuses more on consistency and uniformity, with
stricter guidelines on how iOS apps should look and behave.

ˆ Common Use Cases: Ideal for apps targeting iOS users who expect their apps to
behave and look like native iOS applications.

6.3 Key Dierences

Aspect Material Design (Android) Cupertino Design (iOS)


Platform Focus Android, Web, Desktop iOS
Visual Style Bold, at, geometric, Minimalistic, sleek,
with vivid colors and depth rounded, and subtle
Widget Class MaterialApp CupertinoApp
Design Philosophy Emphasis on motion, Simplicity, clarity, and
interaction, and exibility gesture-driven interfaces
Widgets AppBar, Drawer, CupertinoNavigationBar,
FloatingActionButton CupertinoButton
Customization Highly customizable Limited customization
Highly customizable focused on consistency
Animations Dynamic, uid, Subtle, elegant,
, and bold transitions and smooth transitions
Best For Cross-platform apps with iOS-specic apps with
a consistent look a native iOS feel

Table 2.1: Comparison between Material Design and Cupertino in Flutter

6.4 When to Use Each?


ˆ Material Design is ideal for developing cross-platform apps with a unied look for
Android, iOS, and other platforms. It is especially suited for developers who want more
exibility and customization.

ˆ Cupertino Design is best for apps targeting iOS exclusively or when aiming to provide
a native iOS user experience, ensuring the app adheres to Apple's design standards.

In summary, Material Design is more versatile and exible, making it suitable for cross-
platform applications, while Cupertino oers a focused, iOS-native experience. Flutter allows
developers to combine both systems and adapt their UI to the target platform, ensuring
platform-specic behavior without duplicating eort.
Introduction to Flutter 41

7 Dierence between Stateless and Stateful Widgets in


Flutter
In Flutter, widgets are the building blocks of the user interface. Widgets can be categorized
into two types: Stateless Widgets and Stateful Widgets. The main dierence between
them lies in whether or not the widget can change its state after being built.

7.1 Stateless Widgets


A Stateless Widget is immutable. Once it is built, its properties cannot change. These
widgets are used when the UI does not depend on any dynamic data or changes over time.

ˆ Example from the code: In the Dart code provided earlier, the MyApp widget is an
example of a stateless widget.

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

In this example, the MyApp class extends StatelessWidget. It contains a build method
that returns a widget tree but does not have any state that can change. The UI remains
static once rendered.

7.2 Stateful Widgets


A Stateful Widget is mutable and can change its state dynamically based on user interac-
tion or other events. Stateful widgets maintain state that can change over time, and when
the state changes, Flutter automatically rebuilds the widget to reect the new state.

ˆ Example from the code: The MyHomePage widget in the provided Dart code is a
stateful widget.

class MyHomePage extends StatefulWidget {


MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
42 Introduction to Flutter

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {


int _counter = 0;

void _incrementCounter() {
setState(() {
_counter++;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

In this example, the MyHomePage class extends StatefulWidget, and its state is man-
aged by the _MyHomePageState class. The _counter variable is part of the widget's
Introduction to Flutter 43

state, and it changes every time the button is pressed. The setState method triggers
the widget to rebuild, updating the UI to reect the new counter value.

7.3 Key Dierences


ˆ StatelessWidget: Cannot change once built, suitable for static UI elements.

ˆ StatefulWidget: Can change based on user interaction or other factors, suitable for
dynamic UI elements.

ˆ In the provided code, MyApp is stateless because it does not need to change its state,
while MyHomePage is stateful because it updates the counter when the button is pressed.

8 Dart Programming Language


Dart is a versatile and modern programming language developed by Google, designed for
building high-performance applications across various platforms. Originally introduced in
2011, Dart has evolved into a robust language widely used for both web and mobile devel-
opment, especially with the Flutter framework, which allows for creating natively compiled
applications from a single codebase.
Dart combines features of object-oriented programming with a strong type system, oering
a smooth learning curve for developers familiar with languages like JavaScript, Java, or C#.
Its key strengths include fast performance, simple syntax, and comprehensive tooling, making
it an ideal choice for building scalable, responsive apps. Whether developing for the web,
mobile, or desktop, Dart provides a powerful foundation that emphasizes productivity and
exibility, allowing developers to write ecient code that runs seamlessly across multiple
platforms.
The following subsections are copied from DART main site for educational purposes
https://dart.dev/language

8.1 Hello World


Every app requires the top-level main() function, where execution starts. Functions that
don't explicitly return a value have the void return type. To display text on the console,
you can use the top-level print() function:

void main() {
print('Hello, World!');
}

8.2 Variables
Even in type-safe Dart code, you can declare most variables without explicitly specifying
their type using var. Thanks to type inference, these variables' types are determined by
their initial values:
44 Introduction to Flutter

var name = 'Voyager I';


var year = 1977;
var antennaDiameter = 3.7;
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
var image = {
'tags': ['saturn'],
'url': '//path/to/saturn.jpg'
};

8.3 Control Flow Statements


Dart supports the usual control ow statements:

if (year >= 2001) {


print('21st century');
} else if (year >= 1901) {
print('20th century');
}

for (final object in flybyObjects) {


print(object);
}

for (int month = 1; month <= 12; month++) {


print(month);
}

while (year < 2016) {


year += 1;
}

8.4 Functions
We recommend specifying the types of each function's arguments and return value:

int fibonacci(int n) {
if (n == 0 || n == 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}

var result = fibonacci(20);

A shorthand => (arrow) syntax is handy for functions that contain a single statement.
This syntax is especially useful when passing anonymous functions as arguments:

flybyObjects.where((name) => name.contains('turn')).forEach(print);


Introduction to Flutter 45

8.5 Comments
Dart comments usually start with //.

// This is a normal, one-line comment.

/// This is a documentation comment, used to document libraries,


/// classes, and their members. Tools like IDEs and dartdoc treat
/// doc comments specially.

/* Comments like these are also supported. */

8.6 Imports
To access APIs dened in other libraries, use import.

// Importing core libraries


import 'dart:math';

// Importing libraries from external packages


import 'package:test/test.dart';

// Importing files
import 'path/to/my_other_file.dart';

8.7 Classes
Here's an example of a class with three properties, two constructors, and a method. One
of the properties can't be set directly, so it's dened using a getter method (instead of a
variable). The method uses string interpolation to print variables' string equivalents inside
of string literals.

class Spacecraft {
String name;
DateTime? launchDate;

// Read-only non-final property


int? get launchYear => launchDate?.year;

// Constructor, with syntactic sugar for assignment to members.


Spacecraft(this.name, this.launchDate) {
// Initialization code goes here.
}

// Named constructor that forwards to the default one.


Spacecraft.unlaunched(String name) : this(name, null);
46 Introduction to Flutter

// Method.
void describe() {
print('Spacecraft: $name');
// Type promotion doesn't work on getters.
var launchDate = this.launchDate;
if (launchDate != null) {
int years = DateTime.now().difference(launchDate).inDays ~/ 365;
print('Launched: $launchYear ($years years ago)');
} else {
print('Unlaunched');
}
}
}

You might use the Spacecraft class like this:

var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));


voyager.describe();

var voyager3 = Spacecraft.unlaunched('Voyager III');


voyager3.describe();

8.8 Enums
Enums are a way of enumerating a predened set of values or instances in a way that ensures
there cannot be any other instances of that type.
Here is an example of a simple enum that denes a simple list of predened planet types:

enum PlanetType { terrestrial, gas, ice }

8.9 Inheritance
Dart has single inheritance.

class Orbiter extends Spacecraft {


double altitude;

Orbiter(super.name, DateTime super.launchDate, this.altitude);


}

8.10 Mixins
Mixins are a way of reusing code in multiple class hierarchies. The following is a mixin
declaration:
Introduction to Flutter 47

mixin Piloted {
int astronauts = 1;

void describeCrew() {
print('Number of astronauts: $astronauts');
}
}

To add a mixin's capabilities to a class, just extend the class with the mixin.

class PilotedCraft extends Spacecraft with Piloted {


// ...
}

8.11 Interfaces and Abstract Classes


All classes implicitly dene an interface. Therefore, you can implement any class.

class MockSpaceship implements Spacecraft {


// ...
}

You can create an abstract class to be extended (or implemented) by a concrete class.
Abstract classes can contain abstract methods (with empty bodies).

abstract class Describable {


void describe();

void describeWithEmphasis() {
print('=========');
describe();
print('=========');
}
}

8.12 Async
Avoid callback issues and make your code much more readable by using async and await.

const oneSecond = Duration(seconds: 1);

Future<void> printWithDelay(String message) async {


await Future.delayed(oneSecond);
print(message);
}

The method above is equivalent to:


48 Introduction to Flutter

Future<void> printWithDelay(String message) {


return Future.delayed(oneSecond).then((_) {
print(message);
});
}

8.13 Important Concepts


As you continue to learn about the Dart language, keep these facts and concepts in mind:

ˆ Everything you can place in a variable is an object, and every object is an instance of
a class. Even numbers, functions, and null are objects. With the exception of null (if
you enable sound null safety), all objects inherit from the Object class.

ˆ Version note: Null safety was introduced in Dart 2.12. Using null safety requires a
language version of at least 2.12.

ˆ Although Dart is strongly typed, type annotations are optional because Dart can infer
types. In var number = 101, number is inferred to be of type int.

ˆ If you enable null safety, variables can't contain null unless you say they can. You
can make a variable nullable by putting a question mark (?) at the end of its type.
For example, a variable of type int? might be an integer, or it might be null. If you
know that an expression never evaluates to null but Dart disagrees, you can add ! to
assert that it isn't null (and to throw an exception if it is). An example: int x =
nullableButNotNullInt!
ˆ When you want to explicitly say that any type is allowed, use the type Object? (if
you've enabled null safety), Object, orif you must defer type checking until run-
timethe special type dynamic.

ˆ Dart supports generic types, like List<int> (a list of integers) or List<Object> (a list
of objects of any type).

ˆ Dart supports top-level functions (such as main()), as well as functions tied to a class
or object (static and instance methods, respectively). You can also create functions
within functions (nested or local functions).

ˆ Similarly, Dart supports top-level variables, as well as variables tied to a class or object
(static and instance variables). Instance variables are sometimes known as elds or
properties.

ˆ Unlike Java, Dart doesn't have the keywords public, protected, and private. If
an identier starts with an underscore (_), it's private to its library. For details, see
Libraries and imports.

ˆ Identiers can start with a letter or underscore (_), followed by any combination of
those characters plus digits.
Introduction to Flutter 49

ˆ Dart has both expressions (which have runtime values) and statements (which don't).
For example, the conditional expression condition ? expr1 : expr2 has a value
of expr1 or expr2. Compare that to an if-else statement, which has no value. A
statement often contains one or more expressions, but an expression can't directly
contain a statement.

ˆ Dart tools can report two kinds of problems: warnings and errors. Warnings are just
indications that your code might not work, but they don't prevent your program from
executing. Errors can be either compile-time or run-time. A compile-time error prevents
the code from executing at all; a run-time error results in an exception being raised
while the code executes.

8.14 Additional Resources


You can nd more documentation and code samples in the DART core library documentation
and the Dart API reference at https://dart.dev/language

9 Chapter 2 Review Questions


1. Considering the user experience and design guidelines of both Material Design and
Cupertino Design, how might the choice between these two design systems inuence
the overall look and feel of a Flutter application intended for both Android and iOS
platforms?

2. Given the following Dart code samples:

class MyStatelessWidget extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Text('This is a StatelessWidget');
}
}

class MyStatefulWidget extends StatefulWidget {


@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {


@override
Widget build(BuildContext context) {
return Text('This is a StatefulWidget');
}
}
50 Introduction to Flutter

Reect on how the code structure and behavior of the above widgets might inuence
their use in dierent scenarios within a Flutter application. How would the choice
between a `StatelessWidget` and a `StatefulWidget` aect the development and func-
tionality of your app?

3. Given the partial content of a pubspec.yaml le for a Flutter project:

name: my_flutter_app
description: A new Flutter project

dependencies:
flutter:
sdk: flutter

# Add your dependencies here

dev_dependencies:
flutter_test:
sdk: flutter

flutter:
assets:
# List your assets here

Complete the following sections of the pubspec.yaml le:

(a) Add a dependency for the provider package, specifying its latest version.
(b) Include a list of two assets, such as images or fonts, in the assets section.

Consider how these additions might aect your project's functionality and resource
management.

4. Consider the following incomplete Dart code for a Flutter application, where a `Column`
widget is used to arrange its children:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
Introduction to Flutter 51

home: Scaffold(
appBar: AppBar(
title: Text('Center Alignment Example'),
),
body: Column(
children: <Widget>[
// Add your widgets here
],
// Complete this part to center-align the widgets
),
),
);
}
}

Complete the `Column` widget so that all its child widgets are aligned to the center of
the screen. Use the `mainAxisAlignment` property appropriately to achieve this.

5. Write a Dart function named checkEligibility that takes an integer age as a pa-
rameter and returns a string indicating eligibility for a certain activity. The eligibility
criteria are as follows:

ˆ If age is 18 or older, return "Eligible."


ˆ If age is less than 18, return "Not eligible."

Provide a main function that calls checkEligibility with various ages and prints the
results.

String checkEligibility(int age) {


// Implement the function here
}

void main() {
// Test the function with various ages
}

6. You have been tasked with developing a simple Flutter application that displays a list
of cards with images and text. As part of the development process, you need to ensure
that the layout and structure of the app are correct across dierent devices, and that
you understand how the widgets are structured and rendered.

Task:
52 Introduction to Flutter

(a) Set up a virtual device: Using Android Studio, create and congure a virtual
device that represents a standard Android phone (e.g., Pixel 4). Launch your
Flutter app on this virtual device. Describe the steps you took to create the
virtual device, launch it, and deploy your Flutter app.
(b) Use the Flutter Inspector: Once the app is running, open the Flutter Inspector
in Android Studio. Explain how the Inspector helps you visualize the widget
hierarchy. Describe how you would use the Inspector to verify that the widget
tree matches your expectations.
(c) Analyze the Widget Tree: Using the widget tree in the Flutter Inspector,
describe how you can identify the parent-child relationships between the widgets
in your app. In your explanation, include how the widget tree helps you understand
the structure and layout of the list of cards with images and text.
(d) Investigate the Layout: Open the Layout Explorer and use it to analyze the
padding, margins, and positioning of the widgets in one of the card items in your
app. Provide a summary of what you found and explain how this tool can help
you rene your layout.
(e) Explore the Widget Details Tree: Finally, use the Widget Details Tree to
examine the properties of one of the text widgets in the card. What properties
can you inspect in the Widget Details Tree, and how can this information be useful
for debugging and optimizing the UI?

Deliverables:

ˆ A step-by-step explanation of how you accomplished each of the tasks above.


ˆ Screenshots of the virtual device, Flutter Inspector, widget tree, layout explorer,
and widget details tree during your analysis.
ˆ A brief reection on how these tools can improve your Flutter development work-
ow.

You might also like