Professional Documents
Culture Documents
MD 102 Module 2 1
MD 102 Module 2 1
Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile,
web, and desktop from a single codebase.
In this module we will learn to create a simple UI for our mobile applications.
LEARNING CONTENTS
Flutter’s hot reload feature helps you quickly and easily experiment, build UIs, add
features, and fix bugs..
Hot reload works by injecting updated source code files into the running Dart Virtual
Machine (VM). After the VM updates classes with the new versions of fields and functions,
the Flutter framework automatically rebuilds the widget tree, allowing you to quickly view the
effects of your changes.
1. Run the app from a supported Flutter editor or a termina window. Either a physical or
virtual device can be the target. Only Flutter apps in debug mode can be hot
reloaded.
2. Modify one of the Dart files in your project. Most types of code changes can be hot
reloaded; for a list of changes that require a hot restart.
3. If you’re working in an IDE/editor that supports Flutter’s IDE tools, select Save All
(cmd-s / ctrl-s), or click the hot reload button on the toolbar.
If you’re running the app at the command line using flutter run, enter r in the terminal
window.
After a successful hot reload operation you’ll see a message in the console similar to:
The app updates to reflect your change, and the current state of the app is
preserved. Your app continues to execute from where it was prior to running the hot reload
command. The code updates and execution continues.
What is the difference between hot reload, hot restart, and full restart?
Hot reload loads code changes into the VM and re-builds the widget tree, preserving
the app state; it doesn’t rerun main() or initState(). (ctrl + \ in Intellij and Android
Studio)
Hot restart loads code changes into the VM, and restarts the Flutter app, losing the
app state.
Full restart restarts the iOS, Android, or web app. This takes longer because it also
recompiles the Java/Kotlin/ObjC/Swift code.
Controls for run, run debug, hot reload and hot restart in Android Studio
A code changes has a visible effect only if the modified Dart code is run again after
the change. Specifically, a hot reload causes all of the existing widgets to rebuild. Only code
involved in the rebuilding of the widgets is automatically re-executed. The main() and
initState() functions, for example, are not run again
The pubspec.yaml file is transversal to all aps and packages – it is where we add metadata to our
project, stipulate the Dart and Flutter SDK constraints, and manage the dependencies and also set
Flutter-specific configurations.
When we create a new Flutter Project, we usually have the following file tree:
As we can see, the pubspec.yaml file is divided into different sections, let’s dive deep into each
one.
At the top pf the file we see the name. This field dictates the package name, and also how we will
import files inside this project or from the project. For example, if in one file we want to import the
main.dart function, the import will be as follows:
However, if in the future we change the name field to weather_app_prototype, we have to make
sure to change all of our imports from fantastic_app to weather_app_prototype, which means
that our main.dart import would look like the following:
The description field, as the name implies, is an optional field that let us add a small description
to our project. If we are creating a library, this description is what will be visible to everyone if we
decided to publish our package on pub.dev,
For example for shared_preferences, we have the following description: “Flutter plugin for reading
and writing simple key-value pairs. Wraps SharedPreferences on Android.” and, if we search for
“shared_preferences” at pub.dev, we can see the description in the list of results:
The next parameter, version will allow us to add semantic versioning to the application or library. In
the case of a mobile application, this is going to be the version that appears in the Google Play
Store. A Flutter app with version 1.2.3+4 means that it’s the version 1.2.3 with build version 4.
On the other hand, if we are creating a library, the versioning will give any user the ability to
specify which version of the library they want to use, letting them decide whether to use
shared_preferences: 0.5.12+2 or shared_preferences: 0.1.0.
If we are creating a library project, there are additional optional fields that allows us to give more
information about our package, specifically the author, homepage, issue_tracker and
repository:
Environment
The next section will hold the environment fields. This field allows us to add constraints to both
the Dark SDK and the Flutter Version, which means that when we use:
We are stipulating that this app or library will only run on Dart SDK versions higher or equal than
2.7.0 but lower than 3.0.0. we do not care what specific version it is currently using, only that it
stays between these bounds.
Moreover, we can also stipulate what Flutter version we are going to use, using the flutter
parameter:
In this case, we only allow our app to run if we are using Flutter version of 1.22.0. If we try to get our
packages, through flutter pub get using any other Flutter version we will see the following error:
By using these fields, we can even specify if we are using experimental features, such as sound null
safety. In this case, we can set the Dart SDK constraints to the following:
Dependencies
The next two sections: dependencies and dev_dependencies contain all the package that
we are going to use in the application.
When declaring a dependency to specific package, we must first know the different ways
there are to do add them:
The first one is the most commonly used. We go to pub.dev, select a package, such as bloc
and go to the install section to see how we can add it to our project – by adding the
dependency directly in the pubspec.yaml file in the dependencies section
However, imagine the following scenario: we find a new issue with the bloc package and
decide to clone the repository and fix it ourselves. We solve the issue locally, but then want
to verify if the fix behaves correctly by testing it with our app.
In order to test it, we will need to compile the local bloc version with our app, and to do it
we have to use the path reference. If for example our fix is situated in a directory called
bloc_fixes_issue_110 in the same folder as the parent project, we can reference it by
using …/bloc_fixes_issue_110
Dependency Overrides
Imagine the following scenario: we are using the bloc package with version 6.0.0, but at the
same time we have a dependency on another package that uses 5.0.0. if we try to get the
dependencies for the app, we get the following error:
If we cannot increase the version of the library, or just want to test the application, how can
we do it? By overriding the dependency using
dependency_overrides:
In summary: our package is using flutter_bloc version 5.0.0 and our app is using
version 6.0.0. however, we need to run our app with version 6.0.6, so we override the
dependency. By doing this when pubspec compiles a list of all dependencies, it will use
version 6.0.6 no mater what each app or library stipulates:
When getting the package with this new field, we see a new warning message saying that
we are using an overridden dependency:
Flutter Section
At the bottom of our file, we see a section called flutter. When creating a new project we
see that it already has a parameter: uses-material-design:
This is where we have all the Flutter-specific configuration, such as assets and fonts:
This section used to set each platform’s version of a plugin, when creating a plugin package. Take
as an example the connectivity package which stipulates different platform-specific code for
android, ios, macos and web:
@protected
Widget build(
BuildContext context
)
@protected
The framework calls this method in a number of different situations. For example:
After calling initState.
After calling didUpdateWidget.
After receiving a call to setState.
After a dependency of this State object changes (e.g., an InheritedWidget
referenced by the previous build changes).
After calling deactivate and then reinserting the State object into the tree at
another location
The framework calls this method when this widget is inserted into the tree in a given
BuildContext and when the dependencies of this widget change (e.g., an
InheritedWidget referenced by this widget changes). This method can potentially
be called in every frame and should not have any side effects beyond building a
widget.
The Framework replaces the subtree below this widget with the widget returned by
this method, either by updating the existing subtree or by removing the subtree and
inflating a new subtree, depending on whether the widget returned by this method
can update the root of the existing subtree, as determined by calling
Widget.canUpdate
The given BuildContext contains information about the location in the tree at whice
this widget is being built,
Example: The context provides the set of inherited widgets for this location in tree. A
given widget might be build with multiple different BuildContext argumates over time
if the widget is moved around the tree of it the widget is inserted into the tree in
multiple places one.
the fields of the widget, which themselves must not change over time, and
Implementation
Layout Widgets
The core of Flutter’s layout mechanism is widgets. In flutter, almost everything is a widget –
even layout models are widgets. The images, icons, and text that you see in a Flutter app
are all widgets. But this you don’t see are also widgets, such as the rows, columns, and
grids that arrange, constrain, and align the visible widgets.
The second screenshot displays the visual layout, showing a row of 3 columns where each
column contains an icon and label.
Most of this should look as you might expect, but you might be wondering about the
containers (show in pink). Container is a widget class that allows you to customize its child
widget. Use a Container when you want to add padding, margins, borders or background
color, to name some of its capabilities.
In this example, each Text widget is placed in a Container to add margins. The entire Row
is also placed in a Container to add padding around the row.
The rest of the UI in this example is controlled by properties. Set an Icon’s color using the
color property. Use the Text.style property to set the font, its color, weight, and so on.
Columns and rows have properties that allow you to specify how their children are aligned
vertically or horizontally, and how much space the children should occupy.
In Flutter, it takes only a few steps to put text, an icon, or an image on the screen.
Choose from a variety of layout widgets base on how you want to align or constrain
the visible widget, as these characteristics are typically passed on the contained widget.
A Flutter app is itself a widget, and most widgets have build() method.
Instantiating and returning a widget in the app’s build() method displays the widget.
Material apps
For example Material app, you can use Scaffold widget; it provides a default banner,
background color, and has API for adding drawers, snack bars, and bottom sheets.
Then you can add the Center widget directly to the body property for the home page.
Non-Material apps
For non-material app, you can add the Center widget to the app’s build() method:
That’s it When you run the app, you should see Hello World.
One of the most common layout patterns is to arrange widgets vertically or horizontally.
You can use Row widget to arrange widgets horizontally, and a Column widget to
arrange widgets vertically.
To create a row or column in Flutter, you add a list of children widgets to a Row or
Column widget. In turn, each child can itself be a row or column, and so on. The
following example shows how it is possible to nest rows or columns inside of rows
columns.
This layout is organized as a Row. The row contains two children: a column on the left
and an image on the right:
You’ll implement some of Pavlova’s layout code in Nesting rows and Columns.
Aligning widgets
You control how a row and column aligns its children using mainAxisAlignment and
crossAxisAlignment properties. For a row the main axis runs horizontally and the cross
axis runs vertically. For a column, the main axis runs vertically and the cross axis runs
horizontally.
In the following example, each of the 3 images is 100 pixels wide. The render box (in
case, the entire scree) is more than 300 pixels wide, so setting the main axis alignment
to spaceEvenly divides the free horizontal space evenly between, before, and after each
image
Columns work the same way as rows. The following example shows a column of 3
images, each is 100 pixels, so setting the main axis alignment to spaceEvenly divides
the free vertical space evenly between, above, and below each image.
Flutter has a rich library of layout widgets. Here are a few of those most commonly
used. The intent is to get you up and running as quickly as possible, rather than
overwhelm you with a complete list. For information on other available widgets, refer to
the Widget catalog, or use the Search box in the API reference docs. Also, the widget
pages in the API docs often make suggestions about similar widgets that might better
suits you needs.
The Following widgets fall into two categories: standard widgets from the widgets library,
and specialized widgets from the Material library. Any app can use the widgets library
but only Material apps can use the Material Components library.
Standard Widgets
Container: Adds padding, margins, borders, background color, or other
decorations to a widget.
GridView: Lays widgets out as a scrollable grid.
ListView: Lays widgets out as a scrollable list.
Stack: Overlaps a widget on top of another
Icon Class
To use this class, make sure you set uses-material-design: true in your project
pubspec.yaml file in the flutter section. This to ensure that the MaterialIcons front is
included in your application. This font is used to display the icons.
Example:
This example shows how to create a Row of Icons in different colors and sizes. The
first Icon uses a Icon.semanticLabel to announce in accessibility modes like TalkBack and
VoiceOver.
In this module, we’ve learn all about laravel, its advantages and features, different versions, basics
of Laravel.
REFERENCES
https://medium.com/flutter-community/deep-dive-into-the-pubspec-yaml-file-
fb56ac8683b9#:~:text=Conclusion-
,The%20pubspec.,also%20set%20Flutter%2Dspecific%20configurations.
https://api.flutter.dev/flutter/material/Icons-class.html