Flutter Notes - Revised
Flutter Notes - Revised
Flutter Notes - Revised
Table of Content
Chapter 1: Introduction ............................................................................................................... 4
Installation ................................................................................................................................... 4
Review of Dart Language ........................................................................................................... 4
Assert ....................................................................................................................................... 4
Final and const ......................................................................................................................... 5
Strings ...................................................................................................................................... 5
Lists ......................................................................................................................................... 6
Maps ........................................................................................................................................ 6
Functions ..................................................................................................................................... 7
Chapter 2: Control flow statements ............................................................................................ 9
If and else................................................................................................................................. 9
For loops .................................................................................................................................. 9
While and do-while ............................................................................................................... 10
Break and continue ................................................................................................................ 10
Switch and case ..................................................................................................................... 10
Asynchrony support .................................................................................................................. 12
Handling Futures ....................................................................................................................... 12
Test Drive .................................................................................................................................. 13
Use an external package ............................................................................................................ 13
Stateless and Stateful Widget .................................................................................................... 14
Example: Create an infinite scrolling ListView using ListViewBuilder .................................. 14
Navigation in Flutter ................................................................................................................. 15
Chapter 3: Widget Components ................................................................................................ 17
AppBar ...................................................................................................................................... 17
Drawer ....................................................................................................................................... 19
Images ....................................................................................................................................... 20
Specifying assets ....................................................................................................................... 20
Tabs ........................................................................................................................................... 21
BottomNavigationBar ............................................................................................................... 21
Column ...................................................................................................................................... 22
3
Row ........................................................................................................................................... 23
Container ................................................................................................................................... 23
RaisedButton ............................................................................................................................. 24
Card ........................................................................................................................................... 26
Alert Dialog ............................................................................................................................... 27
Bottom Sheets ........................................................................................................................... 27
ListView .................................................................................................................................... 28
Using Listview Builder .......................................................................................................... 28
Chapter 4: SQLite Database Connection ................................................................................. 30
SQLite ....................................................................................................................................... 30
Chapter 5: Accessing REST API ............................................................................................... 39
Basic Concepts .......................................................................................................................... 39
Accessing Product service API ................................................................................................. 40
Chapter 6: Deployment .............................................................................................................. 51
Android Application .................................................................................................................. 51
iOS Application ......................................................................................................................... 51
Assignment Project ..................................................................................................................... 53
4
Chapter 1: Introduction
Installation
1. Install Android Studio
2. Install flutter
Extract the zip file and place the contained flutter in the desired installation location for the
Flutter SDK (for example, C:\src\flutter).
Under User variables check if there is an entry called Path:
If the entry exists, append the full path to flutter\bin using ; as a separator from
existing values.
To check Licenses
Examples
assert(lineCount == null);
Assert
5
If you never intend to change a variable, use final or const, either instead of var or in addition to a
type. A final variable can be set only once; a const variable is a compile-time constant. (Const
variables are implicitly final.) A final top-level or class variable is initialized the first time it’s used.
Note: Instance variables can be final but not const. Final instance variables must be initialized before
the constructor body starts — at the variable declaration, by a constructor parameter, or in the
constructor’s initializer list.
Here’s an example of creating and setting a final variable:
Use const for variables that you want to be compile-time constants. If the const variable is at the
class level, mark it static const. Where you declare the variable, set the value to a compile-time
constant such as a number or string literal, a const variable, or the result of an arithmetic operation
on constant numbers:
Strings
A Dart string is a sequence of UTF-16 code units. You can use either single or double quotes to
create a string:
You can put the value of an expression inside a string by using ${expression}. If the expression is
an identifier, you can skip the {}. To get the string corresponding to an object, Dart calls the
object’s toString() method.
Lists
Perhaps the most common collection in nearly every programming language is the array, or ordered
group of objects. In Dart, arrays are List objects, so most people just call them lists.
Dart list literals look like JavaScript array literals. Here’s a simple Dart list:
list[1] = 1;
assert(list[1] == 1);
Maps
In general, a map is an object that associates keys and values. Both keys and values can be any
type of object. Each key occurs only once, but you can use the same value multiple times. Dart
support for maps is provided by map literals and the Map type.
Here are a couple of simple Dart maps, created using map literals:
var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
};
7
var nobleGases = {
2: 'helium',
10: 'neon',
18: 'argon',
};
Functions
Dart is a true object-oriented language, so even functions are objects and have a
type, Function. This means that functions can be assigned to variables or passed as arguments to
other functions. You can also call an instance of a Dart class as if it were a function. For details,
see Callable classes.
if and else
for loops
while and do-while loops
break and continue
switch and case
assert
You can also affect the control flow using try-catch and throw, as explained in Exceptions.
If and else
Dart supports if statements with optional else statements, as the next sample shows. Also
see conditional expressions.
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
Unlike JavaScript, conditions must use boolean values, nothing else. See Booleans for more
information.
For loops
You can iterate with the standard for loop. For example:
If the object that you are iterating over is an Iterable, you can use the forEach() method.
Using forEach() is a good option if you don’t need to know the current iteration counter:
10
while (!isDone()) {
doSomething();
}
A do-while loop evaluates the condition after the loop:
do {
printLine();
} while (!atEndOfPage());
while (true) {
if (shutDownRequested()) break;
processIncomingRequests();
}
Use continue to skip to the next loop iteration:
candidates
.where((c) => c.yearsExperience >= 5)
.forEach((c) => c.interview());
Switch statements in Dart compare integer, string, or compile-time constants using ==. The
compared objects must all be instances of the same class (and not of any of its subtypes), and the
class must not override ==. Enumerated types work well in switch statements.
11
Note: Switch statements in Dart are intended for limited circumstances, such as in interpreters
or scanners.
Each non-empty case clause ends with a break statement, as a rule. Other valid ways to end a non-
empty case clause are a continue, throw, or return statement.
case 'CLOSED':
executeClosed();
break;
}
However, Dart does support empty case clauses, allowing a form of fall-through:
case 'CLOSED':
executeClosed();
continue nowClosed;
// Continues executing at the nowClosed label.
nowClosed:
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
Asynchrony support
Dart libraries are full of functions that return Future or Stream objects. These functions
are asynchronous: they return after setting up a possibly time-consuming operation (such as I/O),
without waiting for that operation to complete.
The async and await keywords support asynchronous programming, letting you write asynchronous
code that looks similar to synchronous code.
Handling Futures
When you need the result of a completed Future, you have two options:
Code that uses async and await is asynchronous, but it looks a lot like synchronous code. For
example, here’s some code that uses await to wait for the result of an asynchronous function:
await lookUpVersion();
To use await, code must be in an async function—a function marked as async:
Test Drive
Replace the contents of lib/main.dart.
Delete all of the code from lib/main.dart. Replace with the following code, which displays “Hello
World” in the center of the screen.
import 'package:flutter/material.dart';
3. While viewing the pubspec.yaml file in Android Studio’s editor view, click Pub get.
This pulls the package into your project. You should see the following in the
console:
Stateless Widget
A stateless widget is a widget that describes part of the user interface by building a
constellation of other widgets that describe the user interface more concretely.
15
@override
Widget build(BuildContext context) {
return Container(color: color, child: child);
}
}
Navigation in Flutter
Navigate to a new screen and back
First, create two routes to work with. Since this is a basic example, each route contains
only a single button. Tapping the button on the first route navigates to the second route.
Tapping the button on the second route returns to the first route.
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
}
use onPressed: () {
Navigator.pop(context);
}
17
AppBar
An app bar consists of a toolbar and potentially other widgets, such as a TabBar and a FlexibleSpaceBar.
App bars typically expose one or more common actions with IconButtons which are optionally followed
by a PopupMenuButton for less common operations (sometimes called the "overflow menu").
18
19
Drawer
In Flutter, use the Drawer widget in combination with a Scaffold to create a layout with a
Material Design drawer. This recipe uses the following steps:
1. Create a Scaffold.
2. Add a drawer.
3. Populate the drawer with items.
4. Close the drawer programmatically.
Scaffold(
drawer: Drawer(
child: ListView(
children: [
DrawerHeader(child: Text("Header"),decoration: BoxDecoration(color:
Colors.blue,),),
ListTile(
title: Text("Results"),
)
],
),
),
)
20
Images
Flutter apps can include both code and assets (sometimes called resources). An asset
is a file that is bundled and deployed with your app, and is accessible at runtime.
Common types of assets include static data (for example, JSON files), configuration
files, icons, and images (JPEG, WebP, GIF, animated WebP/GIF, PNG, BMP, and
WBMP).
Specifying assets
Flutter uses the pubspec.yaml file, located at the root of your project, to identify assets
required by an app.
Here is an example:
flutter:
assets:
- assets/images/
As a widget, use
Image.asset('assets/images/banner2.png'),
CircleAvatar(
radius: 60,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 57.0,
backgroundImage: imgurl,
),
),
Or
CircleAvatar(
radius: 18,
child: ClipOval(
child: Image.network(
'image-url',
21
),
),
),
Tabs
The tabs are mainly used for mobile navigation. The styling of tabs is different for
different operating systems.
To add tabs to the app, we need to create a TabBar and TabBarView and attach them
with the TabController. The controller will sync both so that we can have the behavior
which we need.
BottomNavigationBar
This is bottom navigation bar which returns a list of items at the bottom bar.
Column
A widget that displays its children in a vertical array.
To cause a child to expand to fill the available vertical space, wrap the child in an Expanded widget.
The Column widget does not scroll (and in general it is considered an error to have more children in a
Column than will fit in the available room). If you have a line of widgets and want them to be able to
scroll if there is insufficient room, consider using a ListView.
23
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('We move under cover and we move as one'),
Text('Through the night, we have one shot to live another day'),
Text('We cannot let a stray gunshot give us away'),
Text('We will fight up close, seize the moment and stay in it'),
Text('It’s either that or meet the business end of a bayonet'),
Text('The code word is ‘Rochambeau,’ dig me?'),
Text('Rochambeau!', style:
DefaultTextStyle.of(context).style.apply(fontSizeFactor: 2.0)),
],
)
Row
A widget that displays its children in a horizontal array.
To cause a child to expand to fill the available horizontal space, wrap the child in an Expanded widget.
The Row widget does not scroll (and in general it is considered an error to have more children in a Row
than will fit in the available room). If you have a line of widgets and want them to be able to scroll if
there is insufficient room, consider using a ListView.
Row(
children: <Widget>[
Expanded(
child: Text('Deliver features faster', textAlign: TextAlign.center),
),
Expanded(
child: Text('Craft beautiful UIs', textAlign: TextAlign.center),
),
Expanded(
child: FittedBox(
fit: BoxFit.contain, // otherwise the logo will be tiny
child: const FlutterLogo(),
),
),
],
)
Container
A convenience widget that combines common
painting, positioning, and sizing widgets.
Center(
child: Container(
margin: const EdgeInsets.all(10.0),
color: Colors.amber[600],
width: 48.0,
height: 48.0,
),
24
Example2
Container(
constraints: BoxConstraints.expand(
height: Theme.of(context).textTheme.headline4.fontSize * 1.1 + 200.0,
),
padding: const
EdgeInsets.all(8.0),
color: Colors.blue[600],
alignment: Alignment.center,
child: Text('Hello World',
style: Theme.of(context)
.textTheme
.headline4
.copyWith(color:
Colors.white)),
transform:
Matrix4.rotationZ(0.1),
)
RaisedButton
A material design "raised button".
),
),
const SizedBox(height: 30),
RaisedButton(
onPressed: () {},
child: const Text(
'Enabled Button',
style: TextStyle(fontSize: 20)
),
),
const SizedBox(height: 30),
RaisedButton(
onPressed: () {},
textColor: Colors.white,
padding: const EdgeInsets.all(0.0),
child: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: <Color>[
Color(0xFF0D47A1),
Color(0xFF1976D2),
Color(0xFF42A5F5),
],
),
),
padding: const EdgeInsets.all(10.0),
child: const Text(
'Gradient Button',
style: TextStyle(fontSize: 20)
),
),
),
],
),
);
}
26
Card
A card is a sheet used to represent the information related to each other, such as an
album, a geographical location, contact details, etc. A card in Flutter is in rounded
corner shape and has a shadow. We mainly used it to store the content and action
of a single object.
Card(
elevation: 2,
margin: EdgeInsets.all(10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.album),
title: Text('Beauty of Somalia'),
subtitle: Text('Somali kids were playing in a beautiful river..') ),
Image.network('http://i1.trekearth.com/photos/20045/somalia_somali_somalia.jpg'),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
TextButton(
child: const Text('Like'),
onPressed: () {/* ... */},),
const SizedBox(width: 8),
TextButton(
child: const Text('Visit'),
onPressed: () {/* ... */},),
const SizedBox(width: 8),
],
),
],
),
),
27
Alert Dialog
An alert dialog informs the user about situations that require
acknowledgement.
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('AlertDialog’),
content: Text('This is a demo alert dialog.'),
),
},
);
Bottom Sheets
A modal bottom sheet is an alternative to a menu or a dialog and prevents the user from interacting
with the rest of the app.
Center(
child: ElevatedButton(
child: Text('Comment'),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
child: Column(
children:[
Text("Comment"),
TextField(
decoration: InputDecoration(
prefixIcon:Icon(Icons.photo_camera),
suffixIcon:Icon(Icons.send),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.teal)
)),
) ]
) );
},
);
},
), );
28
ListView
ListView is the most commonly used scrolling widget. It displays its children one after another in the
scroll direction. In the cross axis, the children are required to fill the ListView.
ListView(
padding: EdgeInsets.all(8),
children: <Widget>[
Container(
height: 50,
color: Colors.amber[600],
child: Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[100],
child: Center(child: Text('Entry C')),
),
],
)
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('${items[index]}'),
);
},
),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
color: Colors.amber[colorCodes[index]],
child: Center(child: Text('Entry ${entries[index]}')),
);
},
separatorBuilder: (BuildContext context, int index) => const Divider(),
);
30
Flutter provides many advanced packages to work with databases. The most important
packages are −
sqflite − Used to access and manipulate SQLite database, and
SQLite
SQLite database is the de-facto and standard SQL based embedded database engine.
It is small and time-tested database engine. sqflite package provides a lot of
functionality to work efficiently with SQLite database. It provides standard methods to
manipulate SQLite database engine. The core functionality provided by sqflite package
is as follows −
Create / Open (openDatabase method) a SQLite database.
Execute SQL statement (execute method) against SQLite database.
Advanced query methods (query method) to reduce to code required to query
and get information from SQLite database.
Let us create a product application to store and fetch product information from a
standard SQLite database engine using sqflite package and understand the concept
behind the SQLite database and sqflite package.
Create a new Flutter application in Android studio, product_sqlite_app.
Replace the default startup code (main.dart) with our product_rest_app code.
Copy the assets folder from product_nav_app to product_rest_app and add
assets inside the *pubspec.yaml` file.
flutter:
assets:
- assets/appimages/floppy.png
- assets/appimages/iphone.png
- assets/appimages/laptop.png
- assets/appimages/pendrive.png
- assets/appimages/pixel.png
- assets/appimages/tablet.png
Configure sqflite package in the pubspec.yaml file as shown below −
dependencies: sqflite: any
Use the latest version number of sqflite in place of any
Configure path_provider package in the pubspec.yaml file as shown below −
dependencies: path_provider: any
31
Here, path_provider package is used to get temporary folder path of the system
and path of the application. Use the latest version number of sqflite in place
of any.
Android studio will alert that the pubspec.yaml is updated.
Click Get dependencies option. Android studio will get the package from Internet
and properly configure it for the application.
In database, we need primary key, id as additional field along with Product
properties like name, price, etc., So, add id property in the Product class. Also,
add a new method, toMap to convert product object into Map object. fromMap
and toMap are used to serialize and de- serialize the Product object and it is
used in database manipulation methods.
class Product {
final int id;
final String name;
final String description;
final int price;
final String image;
static final columns = ["id", "name", "description", "price",
"image"];
Product(this.id, this.name, this.description, this.price,
this.image);
factory Product.fromMap(Map<String, dynamic> data) {
return Product(
data['id'],
data['name'],
data['description'],
data['price'],
data['image'],
);
}
Map<String, dynamic> toMap() => {
"id": id,
"name": name,
"description": description,
"price": price,
"image": image
};
}
Create a new file, Database.dart in the lib folder to write SQLite related
functionality.
Import necessary import statement in Database.dart.
import 'dart:async';
import 'dart:io';
import 'package:path/path.dart';
32
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'Product.dart';
Note the following points here −
o async is used to write asynchronous methods.
o io is used to access files and directories.
o path is used to access dart core utility function related to file paths.
o path_provider is used to get temporary and application path.
o sqflite is used to manipulate SQLite database.
Create a new class SQLiteDbProvider
Declare a singleton based, static SQLiteDbProvider object as specified below −
class SQLiteDbProvider {
SQLiteDbProvider._();
static final SQLiteDbProvider db = SQLiteDbProvider._();
static Database _database;
}
SQLiteDBProvoider object and its method can be accessed through the static db
variable.
SQLiteDBProvoider.db.<emthod>
Create a method to get database (Future option) of type Future<Database>.
Create product table and load initial data during the creation of the database
itself.
Future<Database> get database async {
if (_database != null)
return _database;
_database = await initDB();
return _database;
}
initDB() async {
Directory documentsDirectory = await
getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, "ProductDB.db");
return await openDatabase(
path,
version: 1,
onOpen: (db) {},
onCreate: (Database db, int version) async {
await db.execute(
"CREATE TABLE Product ("
"id INTEGER PRIMARY KEY,"
"name TEXT,"
33
"description TEXT,"
"price INTEGER,"
"image TEXT" ")"
);
await db.execute(
"INSERT INTO Product ('id', 'name', 'description',
'price', 'image')
values (?, ?, ?, ?, ?)",
[1, "iPhone", "iPhone is the stylist phone ever", 1000,
"iphone.png"]
);
await db.execute(
"INSERT INTO Product ('id', 'name', 'description',
'price', 'image')
values (?, ?, ?, ?, ?)",
[2, "Pixel", "Pixel is the most feature phone ever",
800, "pixel.png"]
);
await db.execute(
"INSERT INTO Product ('id', 'name', 'description',
'price', 'image')
values (?, ?, ?, ?, ?)",
[3, "Laptop", "Laptop is most productive development
tool", 2000, "laptop.png"]\
);
await db.execute(
"INSERT INTO Product ('id', 'name', 'description',
'price', 'image')
values (?, ?, ?, ?, ?)",
[4, "Tablet", "Laptop is most productive development
tool", 1500, "tablet.png"]
);
await db.execute(
"INSERT INTO Product
('id', 'name', 'description', 'price', 'image')
values (?, ?, ?, ?, ?)",
[5, "Pendrive", "Pendrive is useful storage medium",
100, "pendrive.png"]
);
await db.execute(
"INSERT INTO Product
('id', 'name', 'description', 'price', 'image')
values (?, ?, ?, ?, ?)",
[6, "Floppy Drive", "Floppy drive is useful rescue
storage medium", 20, "floppy.png"]
);
}
);
}
34
var id = maxIdResult.first["last_inserted_id"];
var result = await db.rawInsert(
"INSERT Into Product (id, name, description, price, image)"
" VALUES (?, ?, ?, ?, ?)",
[id, product.name, product.description, product.price,
product.image]
);
return result;
}
update(Product product) async {
final db = await database;
var result = await db.update("Product", product.toMap(),
where: "id = ?", whereArgs: [product.id]); return result;
}
delete(int id) async {
final db = await database;
db.delete("Product", where: "id = ?", whereArgs: [id]);
}
The final code of the Database.dart is as follows −
import 'dart:async';
import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'Product.dart';
class SQLiteDbProvider {
SQLiteDbProvider._();
static final SQLiteDbProvider db = SQLiteDbProvider._();
static Database _database;
);
await db.execute(
"INSERT INTO Product ('id', 'name', 'description',
'price', 'image')
values (?, ?, ?, ?, ?)",
[6, "Floppy Drive", "Floppy drive is useful rescue
storage medium", 20, "floppy.png"]
);
}
);
}
Future<List<Product>> getAllProducts() async {
final db = await database;
List<Map> results = await db.query(
"Product", columns: Product.columns, orderBy: "id ASC"
);
List<Product> products = new List();
results.forEach((result) {
Product product = Product.fromMap(result);
products.add(product);
});
return products;
}
Future<Product> getProductById(int id) async {
final db = await database;
var result = await db.query("Product", where: "id = ",
whereArgs: [id]);
return result.isNotEmpty ? Product.fromMap(result.first) :
Null;
}
insert(Product product) async {
final db = await database;
var maxIdResult = await db.rawQuery("SELECT MAX(id)+1 as
last_inserted_id FROM Product");
var id = maxIdResult.first["last_inserted_id"];
var result = await db.rawInsert(
"INSERT Into Product (id, name, description, price,
image)"
" VALUES (?, ?, ?, ?, ?)",
[id, product.name, product.description, product.price,
product.image]
);
return result;
}
update(Product product) async {
final db = await database;
var result = await db.update(
"Product", product.toMap(), where: "id = ?", whereArgs:
[product.id]
38
);
return result;
}
delete(int id) async {
final db = await database;
db.delete("Product", where: "id = ?", whereArgs: [id]);
}
}
Change the main method to get the product information.
void main() {
runApp(MyApp(products: SQLiteDbProvider.db.getAllProducts()));
}
Here, we have used the getAllProducts method to fetch all products from the
database.
Run the application and see the results. It will be similar to previous
example, Accessing Product service API, except the product information is
stored and fetched from the local SQLite database.
Summary
Class _HomeState extends State<Home>{
initState(){
databaseinit() ;
super.initState();
}
databaseinit() async {
var directory = await getApplicationDocumentsDirectory();
String path = directory.path + "armo.db";
Database db = await openDatabase(path, version: 1,
onCreate: (Database mydb, int version) async {
await mydb.execute(
"CREATE TABLE IF NOT EXISTS students(id INTEGER PRIMARY KEY,name TEXT,marks INTEGER)");
});
await db.rawInsert("INSERT INTO students (name,marks) VALUES ('yusuf',40)");
print("Everything is OK");
var results = await db.rawQuery("select * from students");
print(results);
}
Widget build(){}
39
Basic Concepts
http package provides a high level class and http to do web requests.
http class provides functionality to perform all types of HTTP requests.
http methods accept a url, and additional information through Dart Map (post
data, additional headers, etc.,). It requests the server and collects the response
back in async/await pattern. For example, the below code reads the data from
the specified url and print it in the console.
print(await http.read('https://flutter.dev/'));
Some of the core methods are as follows −
read − Request the specified url through GET method and return back the
response as Future<String>
get − Request the specified url through GET method and return back the
response as Future<Response>. Response is a class holding the response
information.
post − Request the specified url through POST method by posting the supplied
data and return back the response as Future<Response>
put − Request the specified url through PUT method and return back the
response as Future <Response>
head − Request the specified url through HEAD method and return back the
response as Future<Response>
delete − Request the specified url through DELETE method and return back the
response as Future<Response>
http also provides a more standard HTTP client class, client. client supports persistent
connection. It will be useful when a lot of request to be made to a particular server. It
needs to be closed properly using close method. Otherwise, it is similar to http class.
The sample code is as follows −
var client = new http.Client();
try {
print(await client.get('https://flutter.dev/'));
}
finally { Future createAlbum(String title) { return
client.close(); http.post( Uri.parse
} ('https://jsonplaceholder.typicode.com/album
s'), headers: String>{ 'Content-Type':
'application/json; charset=UTF-8', },
body: jsonEncode( String>{ 'title': title,
}), );}
40
},
{
"name": "Laptop",
"description": "Laptop is most productive development tool",
"price": 2000,
"image": "laptop.png"
},
{
"name": "Tablet",
"description": "Tablet is the most useful device ever for
meeting",
"price": 1500,
"image": "tablet.png"
},
{
"name": "Pendrive",
"description": "Pendrive is useful storage medium",
"price": 100,
"image": "pendrive.png"
},
{
"name": "Floppy Drive",
"description": "Floppy drive is useful rescue storage
medium",
"price": 20,
"image": "floppy.png"
}
]
Create a new folder, JSONWebServer and place the JSON file, products.json.
Run any web server with JSONWebServer as its root directory and get its web
path. For example, http://192.168.184.1:8000/products.json. We can use any
web server like apache, nginx etc.,
The easiest way is to install node based http-server application. Follow the steps
given below to install and run http- server application
o Install Nodejs application (nodejs.org)
o Go to JSONWebServer folder.
cd /path/to/JSONWebServer
Install http-server package using npm.
npm install -g http-server
Now, run the server.
http-server . -p 8000
Available on:
http://192.168.99.1:8000
http://127.0.0.1:8000
Hit CTRL-C to stop the server
Create a new file, Product.dart in the lib folder and move the Product class into
it.
Write a factory constructor in the Product class, Product.fromMap to convert
mapped data Map into the Product object. Normally, JSON file will be converted
into Dart Map object and then, converted into relevant object (Product).
factory Product.fromJson(Map<String, dynamic> data) {
return Product(
data['name'],
data['description'],
data['price'],
data['image'],
);
}
The complete code of the Product.dart is as follows −
class Product {
final String name;
final String description;
final int price;
final String image;
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: ProductBox(item: items[index]),
onTap: () {
Navigator.push(
context, MaterialPageRoute(
builder: (context) =gt; ProductPage(item:
items[index]),
),
);
},
);
},
);
}
}
Note that we used the same concept used in Navigation application to list the product
except it is designed as a separate widget by passing products (object) of type
List<Product>.
Finally, modify the MyHomePage widget’s build method to get the product
information using Future option instead of normal method call.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Product Navigation")),
body: Center(
child: FutureBuilder<List<Product>>(
future: products, builder: (context, snapshot) {
if (snapshot.hasError) print(snapshot.error);
return snapshot.hasData ? ProductBoxList(items:
snapshot.data)
Here note that we used FutureBuilder widget to render the widget. FutureBuilder
will try to fetch the data from it’s future property (of type Future<List<Product>>).
If future property returns data, it will render the widget using ProductBoxList,
otherwise throws an error.
The complete code of the main.dart is as follows −
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'Product.dart';
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return GestureDetector(
child: ProductBox(item: items[index]),
onTap: () {
Navigator.push(
context, MaterialPageRoute(
builder: (context) => ProductPage(item:
items[index]),
),
);
},
);
},
);
}
}
class ProductPage extends StatelessWidget {
47
});
}
void _setRatingAsTwo() {
setState(() {
_rating = 2;
});
}
void _setRatingAsThree() {
setState(() {
_rating = 3;
});
}
Widget build(BuildContext context) {
double _size = 20;
print(_rating);
return Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
padding: EdgeInsets.all(0),
child: IconButton(
icon: (
_rating >= 1
? Icon(Icons.star, ize: _size,)
: Icon(Icons.star_border, size: _size,)
),
color: Colors.red[500], onPressed:
_setRatingAsOne, iconSize: _size,
),
),
Container(
padding: EdgeInsets.all(0),
child: IconButton(
icon: (
_rating >= 2
? Icon(Icons.star, size: _size,)
: Icon(Icons.star_border, size: _size, )
),
color: Colors.red[500],
onPressed: _setRatingAsTwo,
iconSize: _size,
),
),
Container(
padding: EdgeInsets.all(0),
child: IconButton(
49
icon: (
_rating >= 3 ?
Icon(Icons.star, size: _size,)
: Icon(Icons.star_border, size: _size,)
),
color: Colors.red[500],
onPressed: _setRatingAsThree,
iconSize: _size,
),
),
],
);
}
}
class ProductBox extends StatelessWidget {
ProductBox({Key key, this.item}) : super(key: key);
final Product item;
}
Finally run the application to see the result. It will be same as our Navigation example
except the data is from Internet instead of local, static data entered while coding the
application.
51
Chapter 6: Deployment
Android Application
Change the application name using android:label entry in android manifest file.
Android app manifest file, AndroidManifest.xml is located in <app
dir>/android/app/src/main. It contains entire details about an android application.
We can set the application name using android:label entry.
Change launcher icon using android:icon entry in manifest file.
Sign the app using standard option as necessary.
Enable Proguard and Obfuscation using standard option, if necessary.
Create a release APK file by running below command −
cd /path/to/my/application
flutter build apk
You can see an output as shown below −
Initializing gradle...
8.6s
Resolving dependencies...
19.9s
Calling mockable JAR artifact transform to create file:
/Users/.gradle/caches/transforms-1/files-1.1/android.jar/
c30932f130afbf3fd90c131ef9069a0b/android.jar with input
/Users/Library/Android/sdk/platforms/android-28/android.jar
Running Gradle task 'assembleRelease'...
Running Gradle task 'assembleRelease'...
Done
85.7s
Built build/app/outputs/apk/release/app-release.apk (4.8MB).
Install the APK on a device using the following command −
flutter install
Publish the application into Google Playstore by creating an appbundle and push
it into playstore using standard methods.
flutter build appbundle
iOS Application
Register the iOS application in App Store Connect using standard method. Save
the =Bundle ID used while registering the application.
Update Display name in the XCode project setting to set the application name.
Update Bundle Identifier in the XCode project setting to set the bundle id, which
we used in step 1.
52
Assignment Project
Create a project with a backend server that is an ecommerce based restaurant platform and its data is
saved in an online database. It should have the capability of working even when the user is offline (This
means it should save all its transactions in SQLITE database before synchronizing). Use shimmer in
the splash screen