Session 1
Session 1
Into To Flutter
Birth of Flutter
• Sky
o The goal was to explore ways to achieve consistently high performance across
different platforms.
o Sky showed promise in delivering smooth, jank-free (no stuttering or delays) user
interfaces.
• Flutter's Debut
Key Principles
• Everything is a Widget
o The core philosophy of Flutter is that everything you see on the screen is a widget.
o Widgets are the building blocks of the user interface, ranging from simple buttons
and text to complex layouts and animations.
o This composable nature allows for a great deal of flexibility and customization.
• Hot Reload
o Flutter introduced the "hot reload" feature, which allows developers to see the
changes they make to the code instantly reflected in the running app.
o This dramatically sped up the development process, enabling faster iteration and
experimentation.
• Cross-Platform Consistency
• Community Support
o The Flutter community quickly embraced the framework due to its ease of use,
performance benefits, and the ability to build apps for multiple platforms from a
single codebase.
• Industry Adoption
o Flutter's popularity grew steadily, and many companies started adopting it for their
app development.
o Notable companies using Flutter include Google (for Google Ads and Google Pay),
Alibaba (for Xianyu), BMW, eBay, and many more.
• Expanding Capabilities
o Over time, Flutter's capabilities expanded beyond mobile to include web and
desktop support.
o Flutter also integrated with other Google technologies like Firebase, making it easier
to build full-featured applications.
Flutter Today
o Flutter has matured into a stable and reliable framework for building high-quality
apps across different platforms.
o Flutter is now used for a variety of applications, from consumer apps and games to
enterprise solutions and embedded systems.
• Thriving Ecosystem
o Flutter has a vibrant ecosystem of packages, plugins, and tools that further extend
its capabilities.
o The community continues to be a driving force behind its growth and success.
More on Skia
SKIA
o Flutter apps are built using a hierarchy of widgets, where each widget defines a part
of the user interface.
o When the app starts or when the UI needs to be updated, Flutter builds a tree-like
structure of these widgets, known as the "widget tree."
o Painting: Each widget then describes how it should be painted onto a canvas.
Widgets provide instructions on drawing shapes, text, images, and applying visual
effects.
3. Scene Generation:
o Flutter combines the layout and painting information to create a "scene." This scene
is an abstract representation of what should be rendered on the screen.
o Scene to Skia Commands: The scene is then passed to Skia, Flutter's rendering
engine.
o Skia Canvas: Skia uses its own "canvas" concept to execute drawing commands.
o Drawing: Skia takes the scene description and translates it into a series of low-level
drawing commands, such as drawing lines, filling shapes, applying textures, and
blending colors.
5. Display:
o The final rasterized image generated by Skia is then presented on the device's
screen.
1: The ABCs
1. Basic Syntax and Structure
Hello World:
• void main(): This is the entry point of your Dart program. Execution begins here.
• print(): This function displays the text within the parentheses to the console.
Comments:
• Single-line comments: Start with // and continue to the end of the line.
2. Variables
• var: Use when you want the type to be inferred from the initial value.
• final: Use when the value should not change after initialization. The type can be inferred or
explicitly declared.
• const: Use for compile-time constants. The value and type must be known at compile time.
3. Data Types
• int: Represents whole numbers (integers).
• double: Represents numbers with decimal points (floating-point numbers).
• String: Represents a sequence of characters (text).
• bool: Represents a logical value, either true or false.
• dynamic: Can hold any type of data. Use with caution, as it can lead to runtime type errors.
• if
• if-else
• if-else if-else
• switch
Loops
• for loop
• while loop
• do-while loop
Explanation
• Conditional Statements: These statements allow your program to make decisions and
execute different code blocks based on specific conditions.
• Loops: Loops enable you to repeat a block of code multiple times until a certain
condition is no longer true.
o while: Used when you want to repeat code as long as a condition is true.
o do-while: Similar to while, but the code block is executed at least once before
checking the condition.
3: Functions
3.1. Defining Functions
A function is a block of code that performs a specific task. Here's how to define and use functions
in
3.2. Parameters
Functions can take parameters to perform tasks with given inputs. Dart supports positional,
named, and optional parameters.
You can provide default values for named parameters, which are used if no value is passed during
the function call.
For concise functions, you can use arrow syntax (=>) for functions that contain a single expression.
4: Collections
Dart provides various collection types like Lists, Sets, and Maps. Here are detailed examples for
each collection type:
4.1. Lists
Lists are ordered collections of elements. They can be of fixed or growable length.
Creating and Initializing Lists:
Manipulating Lists:
4.2. Sets
Sets are collections of unique elements.
4.3. Maps
Maps are collections of key-value pairs.
4.4. Iterables
In Dart, an Iterable is an abstract class representing a collection of elements that can be accessed
sequentially. The Iterable class is the base class for collections such as List and Set. Iterables are
very powerful and offer a wide range of methods for manipulation and transformation.
Creating an Iterable
You can create an Iterable using different collection types like List or Set, as they both implement
the Iterable interface.
Accessing Elements
You can access elements of an Iterable using iteration methods like forEach or a for loop.
Here are some common methods provided by the Iterable class in Dart:
• map()
• where()
• reduce()
• fold()
• expand()
• take()
• skip()
1. map()
The map() method transforms each element of an Iterable using a provided function and returns a
new Iterable.
2. where()
The where() method filters elements based on a provided condition and returns a new Iterable.
3. reduce()
The reduce() method combines all elements of an Iterable into a single value using a provided
function.
4. fold()
The fold() method is similar to reduce(), but it allows you to specify an initial value.
5. expand()
The expand() method replaces each element with an Iterable and combines the result into a single
Iterable.
6. take()
The take() method returns the first n elements from an Iterable.
7. skip()
The skip() method skips the first n elements and returns the rest of the Iterable.
Lazy Evaluation
Imagine you have a friend who loves to collect stamps. You ask your friend to show you all the
stamps they have that are blue. Instead of going through their entire collection right away and
picking out all the blue stamps to show you, your friend says, "Okay, I'll find the blue stamps, but
only when you ask to see them one by one."
So, the next time you ask to see a blue stamp, your friend goes through their collection until they
find one and then shows it to you. If you want to see another one, they start from where they left off
and keep looking for the next blue stamp.
This way, your friend doesn't spend a lot of time upfront finding all the blue stamps but instead finds
them as you need them.
Key Points:
1. No Immediate Action: When you define a process using lazy evaluation, no computation or
action is taken right away. The process is just set up.
2. On-Demand Computation: The actual computation or action happens only when you need
the result. In our stamp analogy, the friend looks for blue stamps only when you ask to see
one.
3. Efficiency: This approach can be more efficient because it avoids doing unnecessary work.
If you only ask to see the first two blue stamps, your friend doesn’t waste time finding all the
blue stamps in the collection.
Defining a Class
2. Constructors
Constructors are special methods that are called when an object is instantiated. They initialize the
object's properties.
Default Constructor
Named Constructors
3. Instance Variables and Methods
Instance variables (or fields) hold data for an object, and instance methods define behavior for
the object.
4. Inheritance
Inheritance allows a class to inherit properties and methods from another class.
Base Class
Subclass
5. Polymorphism
Polymorphism allows methods to do different things based on the object it is acting upon.
6. Abstract Classes and Interfaces
Abstract classes cannot be instantiated and are used to define common behavior that other classes
can implement.
Abstract Class
Interface
In Dart, all classes implicitly define an interface. You can implement multiple interfaces by using
the implements keyword.
7. Encapsulation
Encapsulation is the bundling of data and methods that operate on the data within one unit, e.g., a
class. It restricts direct access to some of the object's components.
6. Exception Handling
Try-Catch
The try-catch block is used to gracefully handle exceptions that might occur during the
execution of your code.
• try: Contains the code that you suspect might throw an exception.
• catch (e): Catches the exception and allows you to handle it. The e variable holds the
exception object.
• You can have multiple catch blocks to handle different types of exceptions.
Throwing Exceptions
You can explicitly throw exceptions using the throw keyword.
• throw: Throws an exception object. You can create your own custom exception classes
if needed.
Finally
The finally block is used to execute code regardless of whether an exception occurred or not.
• finally: Contains code that will be executed whether an exception is thrown or not. It's
often used for cleanup tasks like closing files or releasing resources.
7. Asynchronous Programming
Futures
A Future represents a potential value or error that will be available at some time in the future.
It's a way to handle operations that might take some time to complete, like network requests
or file I/O, without blocking the main execution thread.
• Creating a Future
• await: Pauses the execution of the function until the Future completes and returns its
value.
Streams
A Stream is a sequence of asynchronous events. It's useful for handling data that arrives over
time, like user input, sensor data, or real-time updates from a server.
• Creating a Stream
• Listening to a Stream
• async*: Marks a function as an asynchronous generator, allowing it to yield values to a
stream.
• yield: Adds a value to the stream.
• listen: Subscribes to a stream to receive its events.
8. Null Safety
Understanding Null Safety
Null safety is a feature introduced in Dart to help prevent null pointer exceptions at runtime. It
ensures that variables can't hold null values unless you explicitly allow them to.
• Non-nullable types: By default, variables are non-nullable. This means they must be
assigned a non-null value at the time of declaration or later in the code.
• late keyword: The late keyword allows you to declare a non-nullable variable without
initializing it immediately. You promise to initialize it before it's used.
Null-aware operators:
• ?. (null-conditional operator): Safely accesses a property or method of an object that
might be null.
• ?? (null-coalescing operator): Provides a default value if an expression is null.
• ??= (null-aware assignment operator): Assigns a value to a variable only if it's currently
null.
3. Functions
4. Collections
6. Exception Handling
7. Asynchronous Programming
9. Null Safety
• Understanding Null Safety: Non-nullable types, late keyword, null-aware operators (?., ??,
??=).
10. Testing
• Unit Testing: Writing and running unit tests.