0% found this document useful (0 votes)
23 views150 pages

Flutter Mobile App Development 2

This document provides a comprehensive guide on mobile application development using the Flutter framework, focusing on the Dart programming language. It covers fundamental concepts such as variables, data types, control structures, and object-oriented programming, as well as practical examples of Flutter widgets and application design. The document is structured with detailed sections, including code snippets and explanations, aimed at helping developers build mobile applications effectively.

Uploaded by

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

Flutter Mobile App Development 2

This document provides a comprehensive guide on mobile application development using the Flutter framework, focusing on the Dart programming language. It covers fundamental concepts such as variables, data types, control structures, and object-oriented programming, as well as practical examples of Flutter widgets and application design. The document is structured with detailed sections, including code snippets and explanations, aimed at helping developers build mobile applications effectively.

Uploaded by

Aimal Khan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Mobile Application Development

(Flutter Framework)
Dr. Osman Khalid
þ Website: [Link]

Last Updated: 06 June 2024

Table of Contents
Dart Programming Language..........................................................................................................4
Simple Hello World App.....................................................................................................................4
Passing arguments through console..................................................................................................4
Variables............................................................................................................................................5
Variable creation and initialization................................................................................................5
Changing value of variable.............................................................................................................5
We use Object data type, we want to change data type of variable.............................................5
Explicit data types..........................................................................................................................5
Nullable type.................................................................................................................................5
Late variables.................................................................................................................................6
Final and Const..............................................................................................................................6
Constant........................................................................................................................................6
Variable examples.........................................................................................................................6
Conditional expressions:....................................................................................................................7
condition ? expr1 : expr2...............................................................................................................7
expr1 ?? expr2...............................................................................................................................7
Comments:........................................................................................................................................7
Builtin-Types:.....................................................................................................................................8
Strings:...............................................................................................................................................8
String concatenation example:......................................................................................................8
Multiline string:.............................................................................................................................8
Records..............................................................................................................................................8
Lists..................................................................................................................................................10
List of Records:............................................................................................................................11
Sets..................................................................................................................................................11
Maps................................................................................................................................................12
Objects in Dart resembling javascript objects..................................................................................13
List of map objects...........................................................................................................................14
Spread operators.............................................................................................................................14
Control-flow operators....................................................................................................................15
Patterns...........................................................................................................................................15
Variable assignment........................................................................................................................16
Switch statements and expressions.................................................................................................16
For and for-in loops.........................................................................................................................17
Functions:........................................................................................................................................18
Named parameters......................................................................................................................18
Optional positional parameters...................................................................................................19
The main() function.....................................................................................................................20
Functions as first-class objects.....................................................................................................20
Anonymous functions..................................................................................................................21
Arrow notation:...........................................................................................................................22
typdef functions...........................................................................................................................22
Error handling..................................................................................................................................23
Classes.............................................................................................................................................23
Simple class example...................................................................................................................23
No argument constructor............................................................................................................23
One argument generative constructor........................................................................................24
Two argument generative constructor........................................................................................24
Another example of two argument constructor..........................................................................25
Calling a constructor from another constructor within same class..............................................25
Named constructors....................................................................................................................26
Named arguments in a constructor.............................................................................................26
Immutable objects.......................................................................................................................27
Optional arguments to a constructor..........................................................................................27
Array of objects...........................................................................................................................28
Printing elements in an array.......................................................................................................28
Looping through array of objects:................................................................................................29
Use continue to skip to the next loop iteration:.......................................................................30
Inheritance example....................................................................................................................30
Using parent class constructor in child class................................................................................30
Calling named argument constructor from Child class of Parent class........................................31
Flutter widgets.............................................................................................................................32
runApp() function............................................................................................................................32
MaterialApp Widget:.......................................................................................................................35
Scaffold Widget:..............................................................................................................................37
MaterialApp and Material Widget...................................................................................................39
StatelessWidget...............................................................................................................................42
Row widget......................................................................................................................................46
StatefulWidget.................................................................................................................................69
Example: Display message in Text field on button click...............................................................69
Example: A counter application...................................................................................................71
Example: Two counters...............................................................................................................73
Example: Two counters and their sum........................................................................................75
Example: Introducing separate widgets for counter increment and counter display:.................78
Example to take user input using onChanged method and display as Text field.........................80
Assigning value of one TextField to other on button click...........................................................82
Real-time update of one TextField through other.......................................................................83
Example of two TextFields using TextEditingController class and display with button................84
An input form example................................................................................................................86
Shopping Cart with single item:.......................................................................................................89
A shopping cart with multiple Items................................................................................................92
Creating a layout..............................................................................................................................95
Creating a ListView........................................................................................................................101
Creating a horizontal ListView.......................................................................................................102
Creating a Grid List........................................................................................................................104
Create lists with different types of items.......................................................................................106
List with spaced items...................................................................................................................109
Work with long lists:......................................................................................................................111
Theme based styling:.....................................................................................................................113
Add interactivity to our app...........................................................................................................121
Material Components.........................................................................................................121
Drag and Drop...............................................................................................................................121
Input & Forms................................................................................................................................121
Create and style a text field:......................................................................................................121
Retrieve the value of a text field................................................................................................122
Handle changes to a text field...................................................................................................125
Manage focus in text fields........................................................................................................126
Build a form with validation.......................................................................................................128
Navigation and Routing.................................................................................................................130
Working with Tabs:....................................................................................................................130
Navigate to new screen and back:.............................................................................................131
Navigation with CupertinoPageRoute........................................................................................133
Send a string to a new screen....................................................................................................134
Send a string to new screen using RouteSettings......................................................................136
Send data shown in a list to a new screen.................................................................................137
Send data shown in a list to a new screen using RouteSettings.................................................140
Return data from a screen.........................................................................................................141
Add a drawer to a screen...........................................................................................................144
Create a login page in flutter.....................................................................................................147

Dart Programming Language

Simple Hello World App


Create a Dart console application using Visual Studio Code. The following code will be generated.
The calculate() function is defined in lib/[Link].

import 'package:dartproject/[Link]' as dartproject;

void main(List<String> arguments) {


print('Hello world: ${[Link]()}!');

Passing arguments through console


import 'package:dartproject/[Link]' as dartproject;

void main(List<String> arguments) {


print('Arguments: $arguments');
}

To pass the parameters to the above application using console, run the following command in
console:

A:\AAA\flutterprojects\dartproject\bin> dart [Link] one two three

Variables
Variable creation and initialization.
var name = 'Bob';
print(name);

Changing value of variable.


var name = 'Bob';
name = 10; // not allowed to change data type
print(name);

The following code will work.

We use Object data type, we want to change data type of


variable.
Object name = 'Bob';
name = 10;
print(name);

Explicit data types


String name = 'Bob';
print(name);

Nullable type
String? name1; // Nullable type. Can be `null` or string.

String name2; // Non-nullable type. Cannot be `null` but can be


string.

print(name1); // null
// print(name2); // error
Late variables
When you mark a variable as late but initialize it at its declaration, then the initializer runs the first
time the variable is used. This lazy initialization is handy in a couple of cases:

The variable might not be needed, and initializing it is costly.

You're initializing an instance variable, and its initializer needs access to this.

late String description;

void main() {
description = 'Feijoada!';
print(description);
}

Final and Const


A final variable can be set only once; a const variable is a compile-time constant. (Const variables are
implicitly final.)

void main() {
final name = 'Bob'; // Without a type annotation
final String nickname = 'Bobby';

print(name);
print(nickname);

// name = 'Ali'; // This is error as value of final cannot be changed


// after it is initialized.
}

Constant
void main() {
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere
}

Variable examples

void main() {
var name = 'Voyager I';
var year = 1977;
var antennaDiameter = 3.7;
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
var image = {
'tags': ['saturn'],
'url': '//path/to/[Link]'
};

print(name);
print(year);
print(antennaDiameter);
print(flybyObjects);
print(image);

Conditional expressions:
condition ? expr1 : expr2
If condition is true, evaluates expr1 (and returns its value);
otherwise, evaluates and returns the value of expr2.

void main()
{
var isPublic = 'public';
var visibility = isPublic=='public' ? 'public' : 'private';

print(visibility);

expr1 ?? expr2
If expr1 is non-null, returns its value; otherwise, evaluates and
returns the value of expr2.

void main()
{
var var1 = null; // or simply write var var1; this defaults to null
var var2 = 10;

var ans = var1 ?? var2;


print(ans);
}

Comments:
// single line , /* multi line */, /// for documentation.

Builtin-Types:
Numbers, Strings, Booleans.

Strings:
String concatenation example:
void main() {
var s1 = 'String '
'concatenation'
" works even over line breaks.";

print(s1);
}

Multiline string:
void main() {

var s1 = '''
You can create
multi-line strings like this one.
''';

print(s1);
}

Records
Records are an anonymous, immutable, aggregate type. Like other collection
types, they let you bundle multiple objects into a single object. Unlike other
collection types, records are fixed-sized, heterogeneous, and typed.

Records are real values; you can store them in variables, nest them, pass them to and from
functions, and store them in data structures such as lists, maps, and sets.

Example:

void main() {

// Record type annotation in a variable declaration:


({int a, bool b}) record;
// Initialize it with a record expression:
record = (a: 123, b: true);

print(record);
print(record.a);
print(record.b);

Records expressions are comma-delimited lists of named or positional fields, enclosed in


parentheses:

dart

Example:

Here ‘first’, “hello”, ‘last’ are positional fields, and others are named.

void main() {

var record = ('first', a: 2, "hello", b: true, 'last');

print(record.$1); // Prints 'first'


print(record.a); // Prints 2
print(record.b); // Prints true
print(record.$2); // Prints 'last'
print(record.$3);

In a record type annotation, named fields go inside a curly brace-delimited


section of type-and-name pairs, after all positional fields. In a record expression,
the names go before each field value with a colon after:

// Record type annotation in a variable declaration:


({int a, bool b}) record;

// Initialize it with a record expression:


record = (a: 123, b: true);

The names of named fields in a record type are part of the record's type
definition, or its shape. Two records with named fields with different names have
different types:
({int a, int b}) recordAB = (a: 1, b: 2);
({int x, int y}) recordXY = (x: 3, y: 4);

// Compile error! These records don't have the same type.


// recordAB = recordXY;

In a record type annotation, you can also name the positional fields, but these
names are purely for documentation and don't affect the record's type:

(int a, int b) recordAB = (1, 2);


(int x, int y) recordXY = (3, 4);

recordAB = recordXY; // OK.

Example

(int x, int y, int z) point = (1, 2, 3);


(int r, int g, int b) color = (1, 2, 3);

print(point == color); // Prints 'true'.

Example

({int x, int y, int z}) point = (x: 1, y: 2, z: 3);


({int r, int g, int b}) color = (r: 1, g: 2, b: 3);

print(point == color); // Prints 'false'. Lint: Equals on unrelated


types.

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 are denoted by a comma separated list of expressions or values, enclosed in square
brackets ([]). Here's a simple Dart list:

void main() {

var list = [1, 2, 3];

print(list[0]);
}
List of Records:
void main() {

var list = [(id: 1, name:'Ali'), (id: 2, name:'javed')];

for( var item in list) {


print([Link]);
}
}

Sets
#

A set in Dart is an unordered collection of unique items. Dart support for sets is provided by set
literals and the Set type.

Here is a simple Dart set, created using a set literal:

void main() {

var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine',


'astatine'};

print([Link](0));
print([Link](1));

for (var element in halogens)


{
print(element);
}
}

To create an empty set, use {} preceded by a type argument, or assign {} to a variable of type Set:

void main() {

var names = <String>{};


// Set<String> names = {}; // This works, too.
// var names = {}; // Creates a map, not a set.

Add items to an existing set using the add() or addAll() methods:


void main() {

var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine',


'astatine'};
var elements = <String>{};
[Link]('fluorine');
[Link](halogens);

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.

var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
};

var nobleGases = {
2: 'helium',
10: 'neon',
18: 'argon',
};

Add a new key-value pair to an existing map using the subscript assignment operator ([]=):

Dart

var gifts = {'first': 'partridge'};


gifts['fourth'] = 'calling birds'; // Add a key-value pair

Retrieve a value from a map using the subscript operator ([]):

Dart

void main() {

var gifts = {'first': 'partridge'};


assert(gifts['first'] == 'partridge');

}
To print all values of map

void main() {

var nobleGases = {
2: 'helium',
10: 'neon',
18: 'argon',
};

for(var key in [Link]) {


print(nobleGases[key]);
}

You can create the same objects using a Map constructor:

Dart

void main() {

var gifts = Map<String, String>();


gifts['first'] = 'partridge';
gifts['second'] = 'turtledoves';
gifts['fifth'] = 'golden rings';

var nobleGases = Map<int, String>();


nobleGases[2] = 'helium';
nobleGases[10] = 'neon';
nobleGases[18] = 'argon';
}

Add a new key-value pair to an existing map using the subscript assignment operator ([]=):

Dart

var gifts = {'first': 'partridge'};


gifts['fourth'] = 'calling birds'; // Add a key-value pair

Objects in Dart resembling javascript objects


We can define javascript type objects using Map:

Map<String, String> myObject1 = {


'name': 'Devin',
'hairColor': 'brown',
};

print(myObject1);

List of map objects


var list = [
{'name': 'Kamran', 'color' : 'red'},
{'name': 'Shahid', 'color' : 'blue'},
{'name': 'Zahid', 'color' : 'green'},

];

Spread operators
Dart supports the spread operator (...) and the null-aware spread operator (...?) in list, map, and set
literals. Spread operators provide a concise way to insert multiple values into a collection.

For example, you can use the spread operator (...) to insert all the values of a list into another list:

void main() {

var list = [1, 2, 3];


var list2 = [0, ...list];
assert([Link] == 4);
}

If the expression to the right of the spread operator might be null, you can avoid exceptions by using
a null-aware spread operator (...?):

void main() {

var list2 = [0, ...?list];


assert([Link] == 1);

We can modify the map objects using spread operator:

Map<String, String> myObject1 = {


'name': 'Devin',
'hairColor': 'brown',
};
var myObject2 = {...myObject1, 'name':'Kamran'};
print(myObject2);

Control-flow operators
Dart offers collection if and collection for use in list, map, and set literals. You can use these
operators to build collections using conditionals (if) and repetition (for).

Here's an example of using collection if to create a list with three or four items in it:

void main() {

bool promoActive = false;


var nav = ['Home', 'Furniture', 'Plants', if (promoActive) 'Outlet'];
print(nav);
}

void main() {

var login = "Manager";

var nav = ['Home', 'Furniture', 'Plants', if (login case 'Manager')


'Inventory'];

print(nav);
}

Here's an example of using collection for to manipulate the items of a list before adding them to
another list:

void main() {

var listOfInts = [1, 2, 3];


var listOfStrings = ['#0', for (var i in listOfInts) '#$i'];
//assert(listOfStrings[1] == '#1');
print(listOfStrings);
}

Patterns
Destructuring

When an object and pattern match, the pattern can then access the object's data and extract it in
parts. In other words, the pattern destructures the object:

void main() {

var numList = [1, 2, 3];


// List pattern [a, b, c] destructures the three elements from
numList...
var [a, b, c] = numList;
// ...and assigns them to new variables.
print(a + b + c);

Variable assignment
A variable assignment pattern falls on the left side of an assignment. First, it destructures the
matched object. Then it assigns the values to existing variables, instead of binding new ones.

Use a variable assignment pattern to swap the values of two variables without declaring a third
temporary one:

void main() {

var (a, b) = ('left', 'right');


(b, a) = (a, b); // Swap.
print('$a $b'); // Prints "right left".

Switch statements and expressions


Every case clause contains a pattern. This applies to switch statements and expressions, as well as if-
case statements. You can use any kind of pattern in a case.

Case patterns are refutable. They allow control flow to either:

 Match and destructure the object being switched on.

 Continue execution if the object doesn't match.

The values that a pattern destructures in a case become local variables. Their scope is only within the
body of that case.
void main() {

int obj = 3;
const first = 2;
const last = 4;

switch (obj) {
// Matches if 1 == obj.
case 1:
print('one');

// Matches if the value of obj is between the


// constant values of 'first' and 'last'.
case >= first && <= last:
print('in range');

// Matches if obj is a record with two fields,


// then assigns the fields to 'a' and 'b'.
case (var a, var b):
print('a = $a, b = $b');

default:
}

Guard clauses evaluate an arbitrary conditon as part of a case, without exiting the switch if the
condition is false (like using an if statement in the case body would cause).

void main() {
var pair=(20,10);
switch (pair) {
case (int a, int b):
if (a > b) print('First element greater');
// If false, prints nothing and exits the switch.
case (int a, int b) when a > b:
// If false, prints nothing but proceeds to next case.
print('First element greater');
case (int a, int b):
print('First element not greater');
}
}

For and for-in loops


You can use patterns in for and for-in loops to iterate-over and destructure values in a collection.

This example uses object destructuring in a for-in loop to destructure the MapEntry objects that
a <Map>.entries call returns:

void main() {
Map<String, int> hist = {
'a': 23,
'b': 100,
};

for (var MapEntry(key: key, value: count) in [Link]) {


print('$key occurred $count times');
}

Can also be written as:

for (var MapEntry(:key, value: count) in [Link]) {


print('$key occurred $count times');
}

Functions:
bool isNoble(int atomicNumber) {
return true;
}

Although Effective Dart recommends type annotations for public APIs, the function still works if you
omit the types:

isNoble(int atomicNumber) {
return true;
}

For functions that contain just one expression, you can use a shorthand syntax:

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

Named parameters
Named parameters are optional unless they're explicitly marked as required.
When defining a function, use {param1, param2, …} to specify named parameters. If you don't
provide a default value or mark a named parameter as required, their types must be nullable as their
default value will be null:

void main() {
print("Hello world");

enableFlags(); // will assign default null to bold and hidden


enableFlags(bold:true, hidden: true);
}

void enableFlags({bool? bold, bool? hidden}) {

print("$bold $hidden");

To define a default value for a named parameter besides null, use = to specify a default value. The
specified value must be a compile-time constant. For example:

void main() {
print("Hello world");
enableFlags(hidden: false);
}

void enableFlags({bool bold=true, bool hidden=false}) {

print("$bold $hidden");

Optional positional parameters


Wrapping a set of function parameters in [] marks them as optional positional parameters. If you
don't provide a default value, their types must be nullable as their default value will be null:

void main() {
print("Hello world");

say("Ali", "hello"); // calling with two arguments


say("Ali", "hello", "laptop"); // calling with optional argument
included
}

void say(String from, String msg, [String? device]) {


var result = '$from says $msg';
if (device != null) {
result = '$result with a $device';
}
print(result);
}

To define a default value for an optional positional parameter besides null, use = to specify a default
value. The specified value must be a compile-time constant. For example:

void main() {
say("Ali", "hello"); // calling with two arguments
}

void say(String from, String msg, [String device = 'carrier pigeon']) {


print('$from $msg $device');
}

The main() function


Every app must have a top-level main() function, which serves as the
entrypoint to the app. The main() function returns void and has an
optional List<String> parameter for arguments.

Here's a simple main() function:

The file [Link] is in the bin folder. Run the app like this: dart run
[Link] 1 test

// Run the app like this: dart run [Link] 1 test


void main(List<String> arguments) {
print(arguments);

Functions as first-class objects


You can pass a function as a parameter to another function. For example:

void main() {

var list = [1, 2, 3];

// Pass printElement as a parameter.


[Link](printElement);
}

void printElement(int element) {


print(element);
}

You can also assign a function to a variable, such as:

void main() {
var loudify = (msg) => '!!! ${[Link]()} !!!';

print(loudify("hello"));
}

Anonymous functions
Most functions are named, such as main() or printElement(). You can also
create a nameless function called an anonymous function, or sometimes
a lambda or closure. You might assign an anonymous function to a
variable so that, for example, you can add or remove it from a collection.

The following example defines an anonymous function with an untyped


parameter, item, and passes it to the map function. The function, invoked for
each item in the list, converts each string to uppercase. Then in the anonymous
function passed to forEach, each converted string is printed out alongside its
length.

void main() {

const list = ['apples', 'bananas', 'oranges'];

var result = [Link] (

(item)
{
return [Link]();
}
);

print(result);

[Link]((item) {
print('$item: ${[Link]}');
});

/*
// COMBINED FORM
[Link]((item) {
return [Link]();
}).forEach((item) {
print('$item: ${[Link]}');
});
*/

Arrow notation:
Example:

void main() {

const list = ['apples', 'bananas', 'oranges'];

print( [Link]((item) => [Link]()) );

Example:

void main() {

const list = ['apples', 'bananas', 'oranges'];

[Link]((item) => [Link]())


.forEach((item) => print('$item: ${[Link]}'));

typdef functions
// 1. Define a typedef for a function that takes two numbers and
returns their sum
typedef SumFunction = int Function(int a, int b);

void main() {
// 2. Implement a function that matches the SumFunction signature
int add(int a, int b) => a + b;

// 3. Use the SumFunction type to declare a variable and assign the


add function
SumFunction sum = add;

// 4. Call the function using the variable with the SumFunction type
int result = sum(5, 3); // result will be 8

print("Sum of 5 and 3 is: $result");


}

Error handling.

void main() {

misbehave();

void misbehave() {
try {
dynamic foo = true;
print(foo++);
} catch (e) {
print(e);
}
}

Classes
Simple class example
class Point {
double? x; // Declare instance variable x, initially null.
double? y; // Declare y, initially null.
}

void main() {
var point = Point();
point.x = 4; // Use the setter method for x.
print(point.x);

No argument constructor
class Car {

Car() {
print("no argument constructor called");
}

/*
//OR
Car();
*/

void main() {
Car c = Car();

One argument generative constructor


class Car {
String model;
Car([Link]);
}

void main() {
Car c = Car("Toyota");
print([Link]);
}

Two argument generative constructor


import 'dart:math';

class Point {
final double x;
final double y;

// Sets the x and y instance variables


// before the constructor body runs.
Point(this.x, this.y);

double distanceTo(Point other) {


var dx = x - other.x;
var dy = y - other.y;
return sqrt(dx * dx + dy * dy);
}
}

void main() {
Point p1 = Point(10, 20);
print("x: ${p1.x}, y: ${p1.y}");
Point p2 = Point(5, 10);
print([Link](p1));
}

Another example of two argument constructor


If we want to reprocess the variables before assignment to class variables, we can define the
constructor as follows.

class Car {

String? name;
int? age;

Car(name, age){
[Link] = '$name' ' Ali';
[Link] = age + 30;
}

void main() {
Car c = Car("Shahid", 45);

print('${[Link]} ${[Link]}');

Calling a constructor from another constructor within same class.


class Point {
int? x;
int? y;
Point(int a, int b) {
x = a;
y = b;
}

[Link]() : this(10, 20); // Calls the main constructor


}

void main() {
var point1 = Point(3, 4);
var point2 = [Link]();
print('${point1.x} ${point1.y}');
print('${point2.x} ${point2.y}');
}

Named constructors
class User {

[Link]();
[Link]([Link]);
[Link]([Link]);
[Link]([Link], [Link]);

// we can also place class variables after constructors


int? id;
String? name;

void main() {

var user1 = [Link]();


var user2 = [Link](10);
var user3 = [Link]("Javed");
var user4 = [Link](10, "Javed");

print('${[Link]} ${[Link]}');
print('${[Link]} ${[Link]}');
print('${[Link]} ${[Link]}');
print('${[Link]} ${[Link]}');

}
Named arguments in a constructor.
class Person {
String? name;
int age;

Person({required [Link], String? name}) { // Name is optional now


[Link] = name ?? "Unknown"; // Default value for name if not
provided
}
}

void main(){
Person person1 = Person(age: 25); // Specify age first, name is unknown
print('${[Link]} ${[Link]}');

Person person2 = Person(name: "Bob", age: 42); // Specify both in any


order
print('${[Link]} ${[Link]}');

Immutable objects
By adding const, the created object is immutable, its content can’t be changed.

class Teacher {
const Teacher([Link]);
final String name;
}

void main() {
var teacher = const Teacher("Osman");

print([Link]);

//[Link] = "Zahid"; //error

Optional arguments to a constructor


class Person {
final String name;
final int? age; // Can be null

// Constructor with optional age parameter


const Person([Link], {[Link]});
}

void main() {
// Create a Person with name and age
var person1 = Person('Alice', age: 30);

// Create a Person with only name (age will be null)


var person2 = Person('Bob');

print('${[Link]} ${[Link]}');

Array of objects
class Student {

String name;
int age;

// Constructor
Student([Link], [Link]);

void main() {

// Create an array (List) of MyObject instances


List<Student> myObjects = [];

// Add objects to the array


[Link](Student('Alice', 25));
[Link](Student('Bob', 30));
[Link](Student('Charlie', 22));

// Access and print elements in the array


for (Student obj in myObjects) {
print('Name: ${[Link]}, Age: ${[Link]}');
}
}
Printing elements in an array
class Student {

String name;
int age;

// Constructor
Student([Link], [Link]);

void main(List<String> arguments) {

// Create an array (List) of MyObject instances


List<Student> myObjects = [];

// Add objects to the array


[Link](Student('Alice', 25));
[Link](Student('Bob', 30));
[Link](Student('Charlie', 22));

// Access and print elements in the array


[Link]((student) =>
[Link]('Alice')).forEach((student)=>print('Name: $
{[Link]}, Age: ${[Link]}'));

Looping through array of objects:


class Candidate {
final String name;
final int yearsExperience;

Candidate([Link], [Link]);

void interview() {
print("$name is being interviewed...");
// Simulate the interview process
print("$name: Interview went well!");
}
}

void main() {
// List of candidates
List<Candidate> candidates = [
Candidate("Alice", 6),
Candidate("Bob", 3),
Candidate("Charlie", 8),
Candidate("David", 4),
];

// Filter candidates with 5 or more years of experience and conduct


interviews
candidates
.where((c) => [Link] >= 5)
.forEach((c) => [Link]());
}
Use continue to skip to the next loop iteration:

for (int i = 0; i < [Link]; i++) {


var candidate = candidates[i];
if ([Link] < 5) {
continue;
}
[Link]();
}

Inheritance example.
class ParentClass {
void myfunction() {
print("This is parent class function");
}

class ChildClass extends ParentClass {


@override
void myfunction() {
[Link]();
print("This is child class function");
}

}
void main() {

ChildClass c = ChildClass();
[Link]();
}
Using parent class constructor in child class

class Person {

String? name;
int? age;

Person([Link], [Link]);

class Student extends Person { // Explicitly extend the Person class


String? regno;

Student([Link], {String? name = "Ali", int? age = 34}) :


super(name, age);
}

void main() {
Student student = Student("ABC123");
print([Link]); // Output: Ali
print([Link]); // Output: 34
print([Link]); // Output: ABC123
}

Calling named argument constructor from Child class of Parent


class
class Person {
String name;
int age;

Person({required [Link], required [Link]}); // Named arguments


constructor
}

class Student extends Person {


String id;

Student({required [Link], required String name, required int age})


: super(name: name, age: age); // Calling parent constructor with
named arguments
}

void main(){
Student s = Student(id: "334", name:"Jamal", age:34);
print('${[Link]} ${[Link]} ${[Link]}');
}

Flutter widgets
In flutter, widgets act like tags in html containing information/data. Each widget is
represented by class. Widgets call other widgets via class composition principles.

What's the point?

 Widgets are classes used to build UIs.


 Widgets are used for both layout and UI elements.
 Compose simple widgets to build complex 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 things you
don’t see are also widgets, such as the rows, columns, and grids that
arrange, constrain, and align the visible widgets.

runApp() function
The runApp() function takes the given Widget and makes it the root of the widget tree.

Example:
Here the Text wizard is acting as root widget.
NOTE: When MaterialApp widget is used, we don’t need to specify the text direction.
import 'package:flutter/[Link]';

void main() {
runApp(
const Text(
"hello world",
textDirection: [Link],
style: TextStyle(
fontSize: 60,
color: [Link](255, 31, 136, 248),
),
),
);
}

OUTPUT:

Why use const here?


The const keyword used with Text serves two main purposes:
1. Widget Tree Optimization: When you use const with a widget, it tells Flutter that the
widget and its sub-tree (children) are unlikely to change throughout the lifetime of
your app. This allows Flutter to perform some optimizations, such as caching the
widget's configuration and avoiding unnecessary rebuilds. This is particularly
beneficial for widgets that are expensive to create or render.
2. Immutability: Using const with a widget enforces immutability. This means that once
the widget is created, its state cannot be changed. This aligns well with the concept
of widgets in Flutter, which are supposed to represent a declarative UI state.
Key Points:
 The const keyword is most effective for widgets that are stateless and don't require
dynamic updates.
 For widgets that need to update based on user interaction or data changes,
using const might not be suitable. In such cases, you'd likely use
the StatefulWidget approach.
In summary:
Using const with MaterialApp in this example helps Flutter optimize the widget tree and
enforces immutability, which aligns with the principles of building UIs in Flutter.

Example:
To center align the Text, we use Center widget:
In this example, the widget tree consists of two widgets, the Center widget and its child, the
Text widget. The framework forces the root widget to cover the screen, which means the
text “Hello, world” ends up centered on screen.
import 'package:flutter/[Link]';

void main() {
runApp(
const Center(
child: Text(
'Hello, world!',
textDirection: [Link],
),
),
);
}

Output:
MaterialApp Widget:
Many Material Design widgets need to be inside of a MaterialApp to display properly, in
order to inherit theme data. Therefore, run the application with a MaterialApp.
In Flutter, MaterialApp represents a widget that implements the basic material design visual
layout structure. It's typically used as the root widget of a Flutter application. Here's what it
provides:
1. Material Design Components: MaterialApp provides the basic material design
components such as Scaffold, AppBar, Drawer, BottomNavigationBar, SnackBar, and
more. These components follow the Material Design guidelines for visual
appearance and behavior.
2. Text Style Warning: If your app lacks a Material ancestor for text widgets, MaterialApp
automatically applies an ugly red/yellow text style. This serves as a warning to developers
that they haven’t defined a default text style. Typically, the app’s Scaffold defines the text
style for the entire UI.

3. Routing: MaterialApp provides a navigator that manages a stack of Route objects


and a route table for mapping route names to builder functions. This allows you to
navigate between different screens or "routes" in your app using the Navigator
widget.
4. Theme: MaterialApp allows you to define a theme for your entire application using
the theme property. This includes defining colors, typography, shapes, and other
visual properties that are consistent throughout your app.
5. Localization: MaterialApp supports internationalization and localization through the
localizationsDelegates and supportedLocales properties. This allows you to provide
translations for your app's text and adapt its behavior based on the user's locale.
6. Accessibility: MaterialApp includes accessibility features such as support for screen
readers and semantic labels, making your app more accessible to users with
disabilities.
Overall, MaterialApp serves as the foundation for building Flutter apps with material design
principles, providing a consistent and intuitive user experience across different devices and
platforms.

Example:
In this example, MaterialApp widget is made the root widget, and its ‘home’ property is
invoked, in which Text wizard is passed.
import 'package:flutter/[Link]';

void main() {
runApp(const MaterialApp(
home: Text("Hello world"),

));
}

Output:
Scaffold Widget:
While MaterialApp provides the overall structure and theme for a Flutter app, the Scaffold
widget serves as a layout structure for individual screens or "pages" within the app. Here's
what the Scaffold widget provides:
1. App Bar: Scaffold allows you to easily add an app bar at the top of the screen using
the appBar property. The app bar typically contains a title, leading and/or trailing
actions, and may also include other widgets like tabs or a search bar.
2. Body Content: Scaffold's body property is where you place the main content of the
screen. This can be any widget or combination of widgets, such as text, images, lists,
grids, or custom widgets.
3. Navigation Drawer: If your app uses a side navigation drawer, Scaffold provides the
drawer property to easily add one to your screen. The drawer typically contains
navigation links or settings options.
4. Bottom Navigation Bar: For apps with multiple screens or sections, Scaffold allows
you to include a bottom navigation bar using the bottomNavigationBar property.
This allows users to switch between different sections of the app.
5. Floating Action Button: Scaffold provides the floatingActionButton property to add a
floating action button (FAB) to the screen. FABs are typically used for primary or
frequently-used actions, such as adding a new item or starting a new task.
6. Snackbar: Scaffold includes methods for displaying snackbars, which are lightweight
messages that appear at the bottom of the screen. This can be useful for showing
brief feedback or notifications to the user.
Overall, while MaterialApp provides the overall structure and theme for the entire app,
Scaffold provides a consistent layout structure for individual screens, making it easier to
build and organize the UI of your Flutter app.

Example
See how the Point No. 2 of MaterialApp is addressed here when we used Scaffold widget.

import 'package:flutter/[Link]';

void main() {
runApp(const MaterialApp(
home: Scaffold(
body: Center(
child: Text("hello world")
)
)
));
}
MaterialApp and Material Widget

MaterialApp:
 Function: A widget that serves as the foundation for building apps that
follow Google's Material Design guidelines.
 Purpose: Provides a starting point for your app by configuring essential
elements like:
o Theme: Defines the overall look and feel of your app (colors,
fonts, etc.)
o Routing: Manages navigation between different screens in your
app.
o Localization: Enables support for different languages.
o Home: Sets the initial screen displayed when the app launches.
 Placement: Placed at the root of your app's widget tree. There should
typically be only one MaterialApp widget in your app.
Material:
 Function: A basic widget used for creating UI elements that adhere to
Material Design principles.
 Purpose: Defines properties related to the visual appearance and
behavior of individual UI components, such as:
o Elevation: Creates a shadow effect for a 3D-like feel.
o Shape: Defines the shape of the UI element (rounded corners,
etc.).
o Clipping: Controls how the widget's content is displayed within its
bounds.
 Placement: Used throughout your app's widget tree to build various UI
components like buttons, cards, app bars, etc.
Example:
Code snippet

import 'package:flutter/[Link]';

void main() {
runApp(MaterialApp(
home: Scaffold( // Another Material widget for app structure
appBar: AppBar(
title: const Text('My Flutter App'), // Text widget (not
directly from Material)
backgroundColor: [Link], // Defined in ThemeData (part
of MaterialApp)
),
body: Center(
child: Material( // Used for specific UI element
elevation: 4.0, // Material property
shape: RoundedRectangleBorder(borderRadius:
[Link](10.0)),
child: const Text('This is a Material widget'),
),
),
),
));
}
OUTPUT:

In this example:
 MaterialApp configures the app's theme (including the blue color) and
sets the Scaffold as the home screen.
 Scaffold is another Material widget that provides a basic layout structure
for most screens in a Material Design app.
 AppBar and Text are not directly from Material, but they can be styled
within the MaterialApp's theme.
 The Center widget positions the content in the center.
 Finally, the Material widget is used to create a specific button-like
element with elevation and rounded corners.
StatelessWidget
When writing an app, you’ll commonly author new widgets that are subclasses of either
StatelessWidget or StatefulWidget, depending on whether your widget manages any state.
A widget’s main job is to implement a build() function, which describes the widget in terms
of other, lower-level widgets.
Stateless widgets receive arguments from their parent widget, which they store
in final member variables. When a widget is asked to build(), it uses these stored values to
derive new arguments for the widgets it creates.
In Flutter, a StatelessWidget is a fundamental building block for user interfaces (UIs). It
represents a part of your app's UI that remains static throughout its lifetime. Here's a
breakdown of what it means:
Stateless:
 The key characteristic of a StatelessWidget is that it doesn't hold any internal state
that can change. This means its appearance is entirely determined by the
information passed to it when it's created, and it won't update dynamically on its
own.
Widget:
 Everything in Flutter is a widget. Widgets are like building blocks that you assemble
to create your app's UI. A StatelessWidget is a specific type of widget that specializes
in presenting a fixed UI element.
Building UIs:
 StatelessWidgets are ideal for UI elements whose appearance is based on a set of
properties or data provided to them when they are built. They describe how a part
of the UI should look at a given point in time.
Benefits:
 Simpler to create and understand compared to StatefulWidgets (which manage
state).
 More lightweight and efficient for static UI elements.
 Easier to reason about and test due to their predictable behavior.
Common Use Cases:
 Displaying text, icons, images, or simple layouts.
 Building UI elements that only depend on the data passed to them (e.g., displaying a
product name from a list).
 Creating reusable UI components that present a fixed appearance.
In this example, GreetingText is a StatelessWidget that displays the text "Hello World!" with
a specific font size and color. Its appearance remains constant, making it a suitable
candidate for a StatelessWidget.
When to Use StatelessWidgets:
 If a UI element doesn't need to change its appearance based on user interaction or
external data updates, use a StatelessWidget.
 It's a great choice for building simple and reusable UI components.
 For more complex UIs with dynamic behavior, consider using StatefulWidgets.
NOTE:
 Keys are unique identifiers for widgets in Flutter's widget tree.
 They help Flutter track changes to the UI and optimize performance.

Example.
In this example, GreetingText() is a custom defined widget.
 Naming Convention: In Flutter, custom widgets typically start with a capital letter to
differentiate them from built-in widgets provided by the Flutter framework (which
are usually in lowercase).
 The context object serves as a handle that pinpoints a widget's exact position within
the hierarchical structure of widgets that make up your app's UI (User Interface).
 Imagine your app's UI as an inverted tree, with MaterialApp at the root and all other
widgets branching out from it. Context tells a widget exactly where it sits on that
tree.

import 'package:flutter/[Link]';

void main() {
runApp(const MaterialApp(
home: GreetingText(),
));
}

class GreetingText extends StatelessWidget {


const GreetingText({[Link]});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter Greeting'), // Add a title to the
app bar
),
body: const Center( // Center the text within the body
child: Text(
'Hello World!',
style: TextStyle(
fontSize: 32.0,
color: [Link],
),
),
),
);
}
}

Here's a detailed explanation of the code, focusing on the constructor const GreetingText
({[Link]});:
1. Constructor Declaration:
 const GreetingText ({[Link]}): This is the declaration of a constructor for
the GreetingText class. It has some distinct features:
o const Prefix: The const keyword indicates that this constructor creates an
immutable instance of the class. This means that once a GreetingText object
is created, its properties cannot be changed.
o Curly Braces: The curly braces {} enclose a single optional
parameter, [Link].
2. Forwarding Key to Superclass:
 [Link]: This part of the constructor forwards a special parameter named key to
the superclass constructor. In this case, the superclass
is StatelessWidget (since GreetingText extends StatelessWidget).
 Key Importance: Keys are unique identifiers assigned to widgets in Flutter. They play
a crucial role in helping the framework efficiently manage the widget tree and
determine which widgets need to be rebuilt when the UI state changes.
 Forwarding Benefits: By forwarding the key to the superclass, GreetingText inherits
the key management capabilities of StatelessWidget, ensuring proper handling of its
identity and updates within the widget tree.
3. No Explicit Argument:
 You might be wondering why there's no explicit argument being passed to [Link].
This is because key is an optional parameter that can be specified when creating
a GreetingText widget. If a key is not provided, it will default to null.
4. Optional Parameter Syntax:
 The curly braces {} around [Link] signify that it's an optional named parameter.
However, if you don't provide a key, it's perfectly valid to create it without any
arguments:

In summary:
 The constructor const GreetingText ({[Link]}); allows for the creation of
immutable GreetingText widgets with optional keys.
 It forwards the key parameter to the superclass for proper widget management.
 Understanding this syntax and the role of keys is essential for effective Flutter
development.

OUTPUT:
Row widget.
A widget that displays its children in a horizontal array.
In Flutter, the Row widget is a fundamental layout widget used to arrange its child widgets
horizontally in a single row. It's a core building block for creating linear UI elements like:
 Navigation bars with buttons or icons displayed side-by-side.
 Forms with labels and input fields aligned horizontally.
 Layouts with multiple images or text elements displayed in a row.
Key Characteristics:
 Horizontal Arrangement: Child widgets are placed from left to right within the
available space.
 Fixed Size: The Row widget itself doesn't have an intrinsic size. Its size is determined
by the combined size of its child widgets and the available space from the parent
widget.
 Multiple Children: A Row can hold multiple child widgets, allowing you to create
complex horizontal layouts.
Customizing Layout:
While child widgets are placed horizontally by default, you can control their alignment and
distribution within the Row using two properties:
1. MainAxisAlignment: This property determines how the child widgets are positioned
along the main axis (horizontal in this case). Options include:
o [Link] (default): Aligns child widgets to the left edge of the
Row.
o [Link]: Centers child widgets horizontally within the
Row.
o [Link]: Aligns child widgets to the right edge of the Row.
o [Link]: Distributes child widgets evenly with
spaces in between, except for the first and last ones, which are positioned at
the edges.
o [Link]: Distributes child widgets evenly with
spaces around them.
o [Link]: Distributes child widgets with equal space
between them, including the first and last ones.
2. CrossAxisAlignment: This property controls how the child widgets are positioned
along the cross-axis (vertically in this case). Options include:
o [Link] (default): Aligns the top edges of child widgets.
o [Link]: Centers child widgets vertically within the Row.
o [Link]: Aligns the bottom edges of child widgets.
o [Link] (stretches child widgets to fill the vertical space
of the Row).

Example:
Simple example of Row widget.
import 'package:flutter/[Link]';
void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Row Example'),
),
body: const Center(
child: Row(
mainAxisAlignment: [Link],
children: [
Text('Item 1', style: TextStyle(color: [Link])),
Text('Item 2', style: TextStyle(color: [Link])),
Text('Item 3', style: TextStyle(color: [Link])),
],
),
),
),
);
}
}

Output:
Making Child Widgets Flexible:
If a Row has more child widgets than can fit comfortably in the available space, they might
overflow. To handle this, you can wrap child widgets with the Expanded widget. This allows
child widgets to flex and share the available horizontal space proportionally.
If the non-flexible contents of the row (those that are not wrapped
in Expanded or Flexible widgets) are together wider than the row itself, then the row is said
to have overflowed. When a row overflows, the row does not have any remaining space to
share between its Expanded and Flexible children. The row reports this by drawing a yellow
and black striped warning box on the edge that is overflowing. If there is room on the
outside of the row, the amount of overflow is printed in red lettering.

Example:
import 'package:flutter/[Link]';

void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Row Example'),
),
body: const Center(
child: Row(
children: <Widget>[
FlutterLogo(),
Text(
"Flutter's hot reload helps you quickly and easily
experiment, build UIs, add features, and fix bug faster. Experience
sub-second reload times, without losing state, on emulators,
simulators, and hardware for iOS and Android."),
Icon(Icons.sentiment_very_satisfied),
],
),
),
),
);
}
}

Output:
Example:
Controlling text direction in a row:
import 'package:flutter/[Link]';

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

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Row Example'),
),
body: const Center(
child: Row(
textDirection: [Link],
children: <Widget>[
FlutterLogo(),
Expanded(
child: Text(
"Flutter's hot reload helps you quickly and easily
experiment, build UIs, add features, and fix bug faster. Experience
sub-second reload times, without losing state, on emulators,
simulators, and hardware for iOS and Android."),
),
Icon(Icons.sentiment_very_satisfied),
],
),
),
),
);
}
}

Output:

Another example of Expanded widget in Row


Example:
import 'package:flutter/[Link]';

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

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Row Example'),
),
body: const Center(
child: Row(
children: <Widget>[
Expanded(
child: Text('Deliver features faster',
textAlign: [Link]),
),
Expanded(
child: Text('Craft beautiful UIs', textAlign:
[Link]),
),
Expanded(
child: FittedBox(
child: FlutterLogo(),
),
),
],
),
),
),
);
}
}

Output:
Example of mainAxisAlignment using Text widget
import 'package:flutter/[Link]';

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

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Row Example'),
),
body: const Center(
child: Row(
mainAxisAlignment: [Link],
children: <Widget>[
Text("ITEM 1"),
Text("ITEM 2"),
Text("ITEM 3"),
],
),
),
),
);
}
}

Output:
Example of mainAxisAlignment and crossAxisAlignment using SizedBox and Text widget:
import 'package:flutter/[Link]';

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

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Row Example'),
),
body: const Center(
child: Row(
mainAxisAlignment: [Link],
crossAxisAlignment: [Link],
children: <Widget>[
SizedBox(
height: 20.0, // Approach 2: Set height of SizedBox
child: Text('ITEM 1'),
),
SizedBox(
height: 140.0, // Approach 2: Set height of SizedBox
child: Text('ITEM 2'),
),
SizedBox(
height: 20.0, // Approach 2: Set height of SizedBox
child: Text('ITEM 3'),
)
],
),
),
),
);
}
}

Output:
Example of mainAxisAlignment and crossAxisAlignment using Container Widget in Row

NOTE: If the heights of your container widgets are the same as the available space in the
Row, you will see no difference in the crossAxisAlignment behavior.
import 'package:flutter/[Link]';

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

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Row Example'),
),
body: Center(
child: Row(
mainAxisAlignment: [Link],
crossAxisAlignment: [Link],
children: [
Container(
width: 50,
height: 30,
color: [Link],
),
const SizedBox(width: 20),
Container(
width: 50,
height: 70,
color: [Link],
),
const SizedBox(width: 20),
Container(
width: 50,
height: 50,
color: [Link],
),
],
),
),
),
);
}
}

Output:
Column widget example
import 'package:flutter/[Link]';

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

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Row Example'),
),
body: Center(
child: Column(
mainAxisAlignment: [Link],
crossAxisAlignment: [Link],
children: [
Container(
width: 150,
height: 30,
color: [Link],
),
const SizedBox(width: 20),
Container(
width: 80,
height: 70,
color: [Link],
),
const SizedBox(width: 20),
Container(
width: 40,
height: 50,
color: [Link],
),
],
),
),
),
);
}
}
Example of combining different widgets
 The context object serves as a handle that pinpoints a widget's exact position within
the hierarchical structure of widgets that make up your app's UI (User Interface).
 Imagine your app's UI as an inverted tree, with MaterialApp at the root and all other
widgets branching out from it. Context tells a widget exactly where it sits on that
tree.

import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(
title: 'My app', // used by the OS task switcher
home: SafeArea(
child: MyScaffold(),
),
),
);
}

class MyScaffold extends StatelessWidget {


const MyScaffold({[Link]});

@override
Widget build(BuildContext context) {
// Material is a conceptual piece
// of paper on which the UI appears.
return Material(
// Column is a vertical, linear layout.
child: Column(
children: [
MyAppBar(
title: Text(
'Example title',
style: [Link](context) //
.primaryTextTheme
.titleLarge,
),
),
const Expanded(
child: Center(
child: Text('Hello, world!'),
),
),
],
),
);
}
}

class MyAppBar extends StatelessWidget {


const MyAppBar({required [Link], [Link]});

// Fields in a Widget subclass are always marked "final".

final Widget title;

@override
Widget build(BuildContext context) {
return Container(
height: 56, // in logical pixels
padding: const [Link](horizontal: 8),
decoration: BoxDecoration(color: [Link][500]),

// Row is a horizontal, linear layout.


child: Row(
children: [
const IconButton(
icon: Icon([Link]),
tooltip: 'Navigation menu',
onPressed: null, // null disables the button
),
// Expanded expands its child
// to fill the available space.
Expanded(
child: title,
),
const IconButton(
icon: Icon([Link]),
tooltip: 'Search',
onPressed: null,
),
],
),
);
}
}

Output:
Example: Using the MaterialApp and Scaffold Widget with a button
import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(
title: 'Flutter Tutorial',
home: TutorialHome(),
),
);
}

class TutorialHome extends StatelessWidget {


const TutorialHome({[Link]});

@override
Widget build(BuildContext context) {
// Scaffold is a layout for
// the major Material Components.
return Scaffold(
appBar: AppBar(
leading: const IconButton(
icon: Icon([Link]),
tooltip: 'Navigation menu',
onPressed: null,
),
title: const Text('Example title'),
actions: const [
IconButton(
icon: Icon([Link]),
tooltip: 'Search',
onPressed: null,
),
],
),
// body is the majority of the screen.
body: const Center(
child: Text('Hello, world!'),
),
floatingActionButton: const FloatingActionButton(
tooltip: 'Add', // used by assistive technologies
onPressed: null,
child: Icon([Link]),
),
);
}
}

Explanation:

Notice that widgets are passed as arguments to other widgets.


The Scaffold widget takes a number of different widgets as named arguments,
each of which are placed in the Scaffold layout in the appropriate place. Similarly,
the AppBar widget lets you pass in widgets for the leading widget, and
the actions of the title widget. This pattern recurs throughout the framework and
is something you might consider when designing your own widgets.
Example: Adding a simple button and its function:

import 'package:flutter/[Link]';

void main() {
runApp( MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("This is title"),
centerTitle: true,
backgroundColor: [Link],
),
body: Center(
child: Text("This is body") ),
floatingActionButton: FloatingActionButton(
onPressed:() => showHelloWorld(),
child: Text('Click'),

),
)

));
}

void showHelloWorld() {

print("Hello, World!");
// You can replace the print statement with any code to display
"Hello, World!" on the screen.
}

Example: Add a simple button and print message using print function
import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: MyButton(),
),
),
),
);
}

class MyButton extends StatelessWidget {

const MyButton( {[Link]});

@override
Widget build(BuildContext context) {

return GestureDetector(
onTap: () {
print('MyButton was tapped!');
},
child: Container(
height: 50,
padding: const [Link](8),
margin: const [Link](horizontal: 8),
decoration: BoxDecoration(
borderRadius: [Link](5),
color: [Link][500],
),
child: const Center(
child: Text('Engage'),
),
),
);
}
}

Output:
The output will be shown in blue text of debug console.

Example: Add a simple button and print message using ScaffoldMessenger

import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: MyButton(),
),
),
),
);
}

class MyButton extends StatelessWidget {

const MyButton( {[Link]});

@override
Widget build(BuildContext context) {

return GestureDetector(
onTap: () {
[Link](context).showSnackBar(
const SnackBar(
content: Text('MyButton was tapped!'),
backgroundColor: [Link],
),
);
},
child: Container(
height: 50,
padding: const [Link](8),
margin: const [Link](horizontal: 8),
decoration: BoxDecoration(
borderRadius: [Link](5),
color: [Link][500],
),
child: const Center(
child: Text('Engage'),
),
),
);
}
}

The GestureDetector widget doesn’t have a visual representation but instead detects
gestures made by the user. When the user taps the Container, the GestureDetector calls
its onTap() callback, in this case printing a message to the console. You can
use GestureDetector to detect a variety of input gestures, including taps, drags, and scales.
Output:
The blue band at below of screen is output
StatefulWidget
StatefulWidgets are special widgets that know how to generate State objects, which are
then used to hold state.
Example: Display message in Text field on button click
import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: Display(),
),
),
),
);
}
class Display extends StatefulWidget {
const Display({[Link]});

@override
State<Display> createState() => _DisplayState();
}

class _DisplayState extends State<Display> {


String message = ""; // Store the message to display

void _displayMessage() {
setState(() {
message = "Hello World"; // Update the message on button click
});
}

@override
Widget build(BuildContext context) {
return Row( // Modified to display the message
mainAxisAlignment: [Link],
children: <Widget>[
ElevatedButton(
onPressed: _displayMessage, // Call the new function on
button press
child: const Text('Display Message'), // Updated button text
),
const SizedBox(width: 16),
Text(message), // Display the message instead of the Display
],
);
}
}
Example: A counter application
import 'package:flutter/[Link]';

class Counter extends StatefulWidget {


// This class is the configuration for the state.
// It holds the values (in this case nothing) provided
// by the parent and used by the build method of the
// State. Fields in a Widget subclass are always marked
// "final".

const Counter({[Link]});

@override
State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {


int _counter = 0;

void _increment() {
setState(() {
// This call to setState tells the Flutter framework
// that something has changed in this State, which
// causes it to rerun the build method below so that
// the display can reflect the updated values. If you
// change _counter without calling setState(), then
// the build method won't be called again, and so
// nothing would appear to happen.
_counter++;
});
}

@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called,
// for instance, as done by the _increment method above.
// The Flutter framework has been optimized to make
// rerunning build methods fast, so that you can just
// rebuild anything that needs updating rather than
// having to individually changes instances of widgets.
return Row(
mainAxisAlignment: [Link],
children: <Widget>[
ElevatedButton(
onPressed: _increment,
child: const Text('Increment'),
),
const SizedBox(width: 16),
Text('Count: $_counter'),
],
);
}
}

void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: Counter(),
),
),
),
);
}

Output:
Example: Two counters
import 'package:flutter/[Link]';

class Counter extends StatefulWidget {

const Counter({[Link]});

@override
State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {


int _counter1 = 0;
int _counter2 = 0;

void _increment1() {
setState(() {
_counter1++;
});
}

void _increment2() {
setState(() {
_counter2++;
});
}

@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: [Link],
children: <Widget>[
Row(
mainAxisAlignment: [Link],
children: <Widget>[
ElevatedButton(
onPressed: _increment1,
child: const Text('Increment1'),
),
const SizedBox(width: 16),
Text('Count1: $_counter1'),
],
),
Row(
mainAxisAlignment: [Link],
children: <Widget>[
ElevatedButton(
onPressed: _increment2,
child: const Text('Increment'),
),
const SizedBox(width: 16),
Text('Count2: $_counter2'),
],
),
],
);
}
}

void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: Counter(),
),
),
),
);
}
Output:

Example: Two counters and their sum.


import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: Counter(),
),
),
),
);
}

class Counter extends StatefulWidget {

const Counter({[Link]});
@override
State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {


int _counter1 = 0;
int _counter2 = 0;
int _sum = 0;

void _increment1() {
setState(() {
_counter1++;
});
}

void _increment2() {
setState(() {
_counter2++;
});
}

void _sumcounter() {
setState(() {
_sum = _counter1 + _counter2;
});

@override
Widget build(BuildContext context) {
return Column( // Use Column for vertical layout
mainAxisAlignment: [Link], // Center the content
vertically
children: <Widget>[
Row( // First row with a button and Text
mainAxisAlignment: [Link], // Center content
in the row
children: <Widget>[
ElevatedButton(
onPressed: _increment1,
child: const Text('Increment1'),
),
const SizedBox(width: 16), // Spacing between elements
Text('Count: $_counter1'),
],
),
const SizedBox(height: 16), // Spacing between rows
Row( // Second row with another button and Text
mainAxisAlignment: [Link], // Center content
in the row
children: <Widget>[
ElevatedButton(
onPressed: _increment2,
child: const Text('Increment2'),
),
const SizedBox(width: 16), // Spacing between elements
Text('Count: $_counter2'),
],
),
const SizedBox(height: 16), // Spacing between rows
Row( // Second row with another button and Text
mainAxisAlignment: [Link], // Center content
in the row
children: <Widget>[
ElevatedButton(
onPressed: _sumcounter,
child: const Text('Sum'),
),
const SizedBox(width: 16), // Spacing between elements
Text('Ans: $_sum'),
],
),
],
);
}
}

Output:
Example: Introducing separate widgets for counter increment and
counter display:

import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: Counter(),
),
),
),
);
}

class Counter extends StatefulWidget {


const Counter({[Link]});
@override
State<Counter> createState() => _CounterState();
}

class _CounterState extends State<Counter> {


int _counter = 0;

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

@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: [Link],
children: <Widget>[
CounterIncrementor(onPressed: _increment),
const SizedBox(width: 16),
CounterDisplay(count: _counter),
],
);
}
}

class CounterIncrementor extends StatelessWidget {


const CounterIncrementor({required [Link], [Link]});

final VoidCallback onPressed;

@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
child: const Text('Increment'),
);
}
}

class CounterDisplay extends StatelessWidget {


const CounterDisplay({required [Link], [Link]});

final int count;

@override
Widget build(BuildContext context) {
return Text('Count: $count');
}
}

Output:
The output is same to the single counter app.

Example to take user input using onChanged method and display


as Text field
import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: InputDisplay(),
),
),
),
);
}

class InputDisplay extends StatefulWidget {


const InputDisplay({[Link]});

@override
State<InputDisplay> createState() => _InputDisplayState();
}

class _InputDisplayState extends State<InputDisplay> {


String userInput = ""; // Store user input
String message = "";

void _displayInput() {
setState(() {
message = userInput; // Update message with user input
});
}

@override
Widget build(BuildContext context) {
return Column( // Use Column for vertical layout
mainAxisAlignment: [Link],
children: <Widget>[
TextField( // Text input field
onChanged: (value) => setState(() => userInput = value), //
Update userInput on change
decoration: const InputDecoration(
hintText: 'Enter your message', // Hint text for the user
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _displayInput, // Call the function to display
input
child: const Text('Display Input'), // Updated button text
),
const SizedBox(height: 16),
Text(message), // Display the message
],
);
}
}

Output:
Assigning value of one TextField to other on button click
import 'package:flutter/[Link]';

void main() {
runApp(const MaterialApp(
home: Scaffold(
body: Center(
child: InputDisplay(),
)
)
));
}

class InputDisplay extends StatefulWidget {


const InputDisplay({[Link]});

@override
State<InputDisplay> createState() => _InputDisplayState();
}

class _InputDisplayState extends State<InputDisplay> {

String message = "";


String message1="";
String userInput="";

@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: [Link],
children: <Widget>[
TextField(
onChanged: (value) => setState(() => userInput = value
),
decoration: const InputDecoration(
hintText: 'Enter your message'
),
),

ElevatedButton(onPressed: () => setState(

() {
message = userInput;
message1 = userInput;
}
), child: Text("Press button")),

Text(message),
Text(message1),
TextField(
controller: TextEditingController(text: message),
decoration: const InputDecoration(
hintText: 'Enter your message'
),
),
],
);
}

Real-time update of one TextField through other


import 'package:flutter/[Link]';

void main() {
runApp(const MaterialApp(
home: Scaffold(
body: Center(
child: InputDisplay(),
)
)
));
}

class InputDisplay extends StatefulWidget {


const InputDisplay({[Link]});

@override
State<InputDisplay> createState() => _InputDisplayState();
}

class _InputDisplayState extends State<InputDisplay> {

String message = "";


String message1="";
String userInput="";
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: [Link],
children: <Widget>[
TextField(
onChanged: (value) => setState(() => userInput = value
),
decoration: const InputDecoration(
hintText: 'Enter your message'
),
),

TextField(
controller: TextEditingController(text:
[Link]()),
decoration: const InputDecoration(
hintText: 'Enter your message'
),
),
],
);
}

Example of two TextFields using TextEditingController class and


display with button
import 'package:flutter/[Link]';

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

class MyApp extends StatefulWidget {


const MyApp({[Link]});

@override
State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {


// Controllers to store text from each box
final TextEditingController _textController1 =
TextEditingController();
final TextEditingController _textController2 =
TextEditingController();
String _displayText = ""; // Variable to store combined text

void _onPressed() {
// Combine text from controllers and update display text
setState(() {
_displayText = "${_textController1.text} - $
{_textController2.text}";
});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Text Input Example'),
),
body: Center(
child: Column(
mainAxisAlignment: [Link],
children: [
TextField(
controller: _textController1,
decoration: const InputDecoration(
hintText: 'Enter Text 1',
),
),
const SizedBox(height: 10),
TextField(
controller: _textController2,
decoration: const InputDecoration(
hintText: 'Enter Text 2',
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _onPressed,
child: const Text('Display Text'),
),
const SizedBox(height: 10),
Text(_displayText),
],
),
),
),
);
}
}
An input form example
import 'package:flutter/[Link]';

void main() {
runApp(const MaterialApp(
home: ResponsiveForm(),
));
}

class ResponsiveForm extends StatefulWidget {


const ResponsiveForm({[Link]});

@override
State<ResponsiveForm> createState() => _ResponsiveFormState();
}

class _ResponsiveFormState extends State<ResponsiveForm> {


// Add state variables for form fields
final _nameController = TextEditingController();
final _emailController = TextEditingController();
final _phoneController = TextEditingController();
final _addressController = TextEditingController();

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('User Information Form'),
),
body: SingleChildScrollView(
padding: const [Link](20.0),
child: LayoutBuilder(
builder: (context, constraints) {
return Row(
children: [
Expanded(
child: _buildForm(context),
),
],
);
},
),
),
);
}

Widget _buildForm(BuildContext context) {


return Column(
crossAxisAlignment: [Link],
children: [
TextField(
controller: _nameController,
decoration: const InputDecoration(
labelText: 'Name',
),
),
const SizedBox(height: 10.0),
TextField(
controller: _emailController,
decoration: const InputDecoration(
labelText: 'Email',
),
keyboardType: [Link],
),
const SizedBox(height: 10.0),
TextField(
controller: _phoneController,
decoration: const InputDecoration(
labelText: 'Phone Number',
),
keyboardType: [Link],
),
const SizedBox(height: 10.0),
TextField(
controller: _addressController,
decoration: const InputDecoration(
labelText: 'Address',
),
maxLines: null, // This allows multiline input
),
const SizedBox(height: 20.0),
Row(
children: [
const SizedBox(width: 2.0),
ElevatedButton(
onPressed: () => showValues(context),
child: const Text('Submit'),
),
const SizedBox(width: 10.0),
ElevatedButton(
onPressed: () => {},
child: const Text('Clear'),
),
],
),
],
);
}

void showValues(BuildContext context) {


// Print the current values of the form fields
debugPrint('Name: ${_nameController.text}');
debugPrint('Email: ${_emailController.text}');
debugPrint('Phone: ${_phoneController.text}');
debugPrint('Address: ${_addressController.text}');

[Link](context).showSnackBar(
const SnackBar(
content: Text('Form is submitted!'),
backgroundColor: [Link],
),
);

}
}

Output:
Shopping Cart with single item:
import 'package:flutter/[Link]';

void main() {
runApp(
MaterialApp(
home: Scaffold(
body: Center(
child: ShoppingListItem(
product: const Product(name: 'Chips'),
inCart: true,
onCartChanged: (product, inCart) {},
),
),
),
),
);
}

typedef CartChangedCallback = Function(Product product, bool inCart);

class ShoppingListItem extends StatelessWidget {

final Product product;


final bool inCart;
final CartChangedCallback onCartChanged;

ShoppingListItem({
required [Link],
required [Link],
required [Link],
}) : super(key: ObjectKey(product));

// The below two methods _getColor and _getTextStyle are related to


styling //

Color _getColor(BuildContext context) {


// The theme depends on the BuildContext because different
// parts of the tree can have different themes.
// The BuildContext indicates where the build is
// taking place and therefore which theme to use.
return inCart //
? Colors.black54
: [Link](context).primaryColor;
}

TextStyle? _getTextStyle(BuildContext context) {


if (!inCart) return null;

return const TextStyle(


color: Colors.black54,
decoration: [Link],
);
}

@override
Widget build(BuildContext context) {
return ListTile(
onTap: () {
onCartChanged(product, inCart);
},
leading: CircleAvatar(
backgroundColor: _getColor(context),
child: Text([Link][0]),
),
title: Text([Link], style: _getTextStyle(context)),
);
}
}

class Product {
const Product({required [Link]});

final String name;


}
A shopping cart with multiple Items
import 'package:flutter/[Link]';

void main() {
runApp(const MaterialApp(
title: 'Shopping App',
home: ShoppingList(
products: [
Product(name: 'Eggs'),
Product(name: 'Flour'),
Product(name: 'Chocolate chips'),
],
),
));
}

class Product {
const Product({required [Link]});

final String name;


}

typedef CartChangedCallback = Function(Product product, bool inCart);


class ShoppingListItem extends StatelessWidget {
ShoppingListItem({
required [Link],
required [Link],
required [Link],
}) : super(key: ObjectKey(product));

final Product product;


final bool inCart;
final CartChangedCallback onCartChanged;

Color _getColor(BuildContext context) {


// The theme depends on the BuildContext because different
// parts of the tree can have different themes.
// The BuildContext indicates where the build is
// taking place and therefore which theme to use.

return inCart //
? Colors.black54
: [Link](context).primaryColor;
}

TextStyle? _getTextStyle(BuildContext context) {


if (!inCart) return null;

return const TextStyle(


color: Colors.black54,
decoration: [Link],
);
}

@override
Widget build(BuildContext context) {
return ListTile(
onTap: () {
onCartChanged(product, inCart);
},
leading: CircleAvatar(
backgroundColor: _getColor(context),
child: Text([Link][0]),
),
title: Text(
[Link],
style: _getTextStyle(context),
),
);
}
}
class ShoppingList extends StatefulWidget {
const ShoppingList({required [Link], [Link]});

final List<Product> products;

// The framework calls createState the first time


// a widget appears at a given location in the tree.
// If the parent rebuilds and uses the same type of
// widget (with the same key), the framework re-uses
// the State object instead of creating a new State object.

@override
State<ShoppingList> createState() => _ShoppingListState();
}

class _ShoppingListState extends State<ShoppingList> {


final _shoppingCart = <Product>{};

void _handleCartChanged(Product product, bool inCart) {


setState(() {
// When a user changes what's in the cart, you need
// to change _shoppingCart inside a setState call to
// trigger a rebuild.
// The framework then calls build, below,
// which updates the visual appearance of the app.

if (!inCart) {
_shoppingCart.add(product);
} else {
_shoppingCart.remove(product);
}
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Shopping List'),
),
body: ListView(
padding: const [Link](vertical: 8),
children: [Link]((product) {
return ShoppingListItem(
product: product,
inCart: _shoppingCart.contains(product),
onCartChanged: _handleCartChanged,
);
}).toList(),
),
);
}
}

Creating a layout
To include images, add an assets tag to the [Link] file at the root
directory of your app. When you add assets, it serves as the set of pointers
to the images available to your code.

@@ -19,3 +19,5 @@
19
flutter:
19
20
uses-material-design: true
20
21 + assets:
22 + - images/[Link]
import 'package:flutter/[Link]';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
const String appTitle = 'Flutter layout demo';
return MaterialApp(
title: appTitle,
home: Scaffold(
appBar: AppBar(
title: const Text(appTitle),
),
body: const Center(
child: const SingleChildScrollView(
child: Column(
children: [
ImageSection(
image: 'images/[Link]',
),
TitleSection(
name: 'Oeschinen Lake Campground',
location: 'Kandersteg, Switzerland',
),
ButtonSection(),
TextSection(
description:
'Lake Oeschinen lies at the foot of the Blüemlisalp
in the '
'Bernese Alps. Situated 1,578 meters above sea
level, it '
'is one of the larger Alpine Lakes. A gondola ride
from '
'Kandersteg, followed by a half-hour walk through
pastures '
'and pine forest, leads you to the lake, which
warms to 20 '
'degrees Celsius in the summer. Activities enjoyed
here '
'include rowing, and riding the summer toboggan
run.',
),
],
)),
),
),
);
}
}

class TitleSection extends StatelessWidget {


const TitleSection({
[Link],
required [Link],
required [Link],
});

final String name;


final String location;

@override
Widget build(BuildContext context) {
return Padding(
padding: const [Link](32),
child: Row(
children: [
Expanded(
/*1*/
child: Column(
crossAxisAlignment: [Link],
children: [
/*2*/
Padding(
padding: const [Link](bottom: 8),
child: Text(
name,
style: const TextStyle(
fontWeight: [Link],
),
),
),
Text(
location,
style: TextStyle(
color: [Link][500],
),
),
],
),
),
/*3*/
Icon(
[Link],
color: [Link][500],
),
const Text('41'),
],
),
);
}
}

class ButtonSection extends StatelessWidget {


const ButtonSection({[Link]});

@override
Widget build(BuildContext context) {
final Color color = [Link](context).primaryColor;
return SizedBox(
child: Row(
mainAxisAlignment: [Link],
children: [
ButtonWithText(
color: color,
icon: [Link],
label: 'CALL',
),
ButtonWithText(
color: color,
icon: Icons.near_me,
label: 'ROUTE',
),
ButtonWithText(
color: color,
icon: [Link],
label: 'SHARE',
),
],
),
);
}
}

class ButtonWithText extends StatelessWidget {


const ButtonWithText({
[Link],
required [Link],
required [Link],
required [Link],
});
final Color color;
final IconData icon;
final String label;

@override
Widget build(BuildContext context) {
return Column(
// ···
);
}
}

class TextSection extends StatelessWidget {


const TextSection({
[Link],
required [Link],
});

final String description;

@override
Widget build(BuildContext context) {
return Padding(
padding: const [Link](32),
child: Text(
description,
softWrap: true,
),
);
}
}

class ImageSection extends StatelessWidget {


const ImageSection({[Link], required [Link]});

final String image;

@override
Widget build(BuildContext context) {
return [Link](
image,
width: 600,
height: 240,
fit: [Link],
);
}
}
Creating a ListView
import 'package:flutter/[Link]';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
const title = 'Basic List';

return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body: ListView(
children: const <Widget>[
ListTile(
leading: Icon([Link]),
title: Text('Map'),
),
ListTile(
leading: Icon(Icons.photo_album),
title: Text('Album'),
),
ListTile(
leading: Icon([Link]),
title: Text('Phone'),
),
],
),
),
);
}
}

Output:

Creating a horizontal ListView


import 'package:flutter/[Link]';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
const title = 'Horizontal List';

return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body: Container(
margin: const [Link](vertical: 20),
height: 200,
child: ListView(
// This next line does the trick.
scrollDirection: [Link],
children: <Widget>[
Container(
width: 160,
color: [Link],
),
Container(
width: 160,
color: [Link],
),
Container(
width: 160,
color: [Link],
),
Container(
width: 160,
color: [Link],
),
Container(
width: 160,
color: [Link],
),
],
),
),
),
);
}
}
Creating a Grid List
import 'package:flutter/[Link]';

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

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
const title = 'Grid List';

return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body: [Link](
// Create a grid with 2 columns. If you change the
scrollDirection to
// horizontal, this produces 2 rows.
crossAxisCount: 2,
// Generate 100 widgets that display their index in the List.
children: [Link](100, (index) {
return Center(
child: Text(
'Item $index',
style: [Link](context).[Link],
),
);
}),
),
),
);
}
}

Output:
Create lists with different types of items
import 'package:flutter/[Link]';

void main() {
runApp(
MyApp(
items: List<ListItem>.generate(
1000,
(i) => i % 6 == 0
? HeadingItem('Heading $i')
: MessageItem('Sender $i', 'Message body $i'),
),
),
);
}

class MyApp extends StatelessWidget {


final List<ListItem> items;

const MyApp({[Link], required [Link]});

@override
Widget build(BuildContext context) {
const title = 'Mixed List';

return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body: [Link](
// Let the ListView know how many items it needs to build.
itemCount: [Link],
// Provide a builder function. This is where the magic
happens.
// Convert each item into a widget based on the type of item
it is.
itemBuilder: (context, index) {
final item = items[index];

return ListTile(
title: [Link](context),
subtitle: [Link](context),
);
},
),
),
);
}
}

/// The base class for the different types of items the list can
contain.
abstract class ListItem {
/// The title line to show in a list item.
Widget buildTitle(BuildContext context);

/// The subtitle line, if any, to show in a list item.


Widget buildSubtitle(BuildContext context);
}

/// A ListItem that contains data to display a heading.


class HeadingItem implements ListItem {
final String heading;

HeadingItem([Link]);

@override
Widget buildTitle(BuildContext context) {
return Text(
heading,
style: [Link](context).[Link],
);
}

@override
Widget buildSubtitle(BuildContext context) => const
[Link]();
}

/// A ListItem that contains data to display a message.


class MessageItem implements ListItem {
final String sender;
final String body;

MessageItem([Link], [Link]);

@override
Widget buildTitle(BuildContext context) => Text(sender);

@override
Widget buildSubtitle(BuildContext context) => Text(body);
}

Output:
List with spaced items
import 'package:flutter/[Link]';

void main() => runApp(const SpacedItemsList());

class SpacedItemsList extends StatelessWidget {


const SpacedItemsList({[Link]});

@override
Widget build(BuildContext context) {
const items = 4;

return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: [Link](seedColor:
[Link]),
cardTheme: CardTheme(color: [Link].shade50),
useMaterial3: true,
),
home: Scaffold(
body: LayoutBuilder(builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight:
[Link]),
child: Column(
mainAxisAlignment: [Link],
crossAxisAlignment: [Link],
children: [Link](
items, (index) => ItemWidget(text: 'Item $index')),
),
),
);
}),
),
);
}
}

class ItemWidget extends StatelessWidget {


const ItemWidget({
[Link],
required [Link],
});

final String text;

@override
Widget build(BuildContext context) {
return Card(
child: SizedBox(
height: 100,
child: Center(child: Text(text)),
),
);
}
}

Output:
Work with long lists:
import 'package:flutter/[Link]';

void main() {
runApp(
MyApp(
items: List<String>.generate(10000, (i) => 'Item $i'),
),
);
}

class MyApp extends StatelessWidget {


final List<String> items;

const MyApp({[Link], required [Link]});

@override
Widget build(BuildContext context) {
const title = 'Long List';

return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: const Text(title),
),
body: [Link](
itemCount: [Link],
prototypeItem: ListTile(
title: Text([Link]),
),
itemBuilder: (context, index) {
return ListTile(
title: Text(items[index]),
);
},
),
),
);
}
}

Output:
Theme based styling:

To share colors and font styles throughout an app, use themes.

You can define app-wide themes. You can extend a theme to change a
theme style for one component. Each theme defines the colors, type style,
and other parameters applicable for the type of Material component.

Flutter applies styling in the following order:


1. Styles applied to the specific widget.
2. Themes that override the immediate parent theme.
3. Main theme for the entire app.

After you define a Theme, use it within your own widgets. Flutter's Material
widgets use your theme to set the background colors and font styles for
app bars, buttons, checkboxes, and more.

This code includes the theme settings and applies them to the Container widget
in the MyHomePage . The GoogleFonts package is used to customize text
themes. Make sure you have the google_fonts package added in your
[Link] :

dependencies:

flutter:

sdk: flutter

google_fonts: ^4.0.0

Example:
import 'package:flutter/[Link]';
import 'package:google_fonts/google_fonts.dart';

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

ThemeData myTheme = ThemeData(


useMaterial3: true,
textTheme: TextTheme(
bodyLarge: TextStyle(
fontSize: 16.0,
),
displayLarge: TextStyle(
fontSize: 72,
fontWeight: [Link],
),
titleLarge: [Link](
fontSize: 30,
fontStyle: [Link],
),
bodyMedium: [Link](),
displaySmall: [Link](),
),
colorScheme: [Link](
//primary: [Link],
//secondary: [Link],
seedColor: const Color(0xFF33CC99),
//brightness: [Link],
),
);

// create another ThemeData

ThemeData myTheme1 = ThemeData(


useMaterial3: true,
textTheme: TextTheme(
bodyLarge: TextStyle(
fontSize: 80.0,
),
displayLarge: TextStyle(
fontSize: 40,
fontStyle: [Link],
fontWeight: [Link],
),
titleLarge: [Link](
fontSize: 30,
//fontStyle: [Link],
),
bodyMedium: [Link](),
displaySmall: [Link](),
),
colorScheme:
[Link](seedColor: [Link](255, 249, 15,
15)),
);

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
const appName = 'Custom Themes';

return MaterialApp(
title: appName,
theme: myTheme,
home: const MyHomePage(
title: appName,
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;

const MyHomePage({[Link], required [Link]});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title,
style: [Link](context).[Link]!.copyWith(
color: [Link](context).[Link],
)),
backgroundColor: [Link](context).[Link],
),
body: Column(mainAxisAlignment: [Link],
children: [
Center(
child: Container(
padding: const [Link](
horizontal: 12,
vertical: 12,
),
color: [Link](context).[Link],
child: Text(
'Text with a background color',
// TRY THIS: change the [Link](context).textTheme
// to "displayLarge" or "displaySmall".
style: [Link](context).[Link]!.copyWith(
color: [Link](context).[Link],
),
),
),
),
Text("Message 1",
style: TextStyle(
fontSize:
[Link](context).[Link]!.fontSize)),
Text("Message 2", style:
[Link](context).[Link]),
Text("Message 3", style:
[Link](context).[Link]),
Text(
"Message 4",
style: [Link](context).[Link]!.copyWith(
color: [Link](context).[Link],
),
),
Theme(data: myTheme1, child: MyCustomWidget())
]),
floatingActionButton: Theme(
data: [Link](context).copyWith(
// TRY THIS: Change the seedColor to "[Link]" or
// "[Link]".
colorScheme: [Link](
seedColor: [Link],
brightness: [Link],
),
),
child: FloatingActionButton(
onPressed: () {},
child: const Icon([Link]),
),
),
);
}
}

class MyCustomWidget extends StatelessWidget {


const MyCustomWidget({[Link]});

@override
Widget build(BuildContext context) {
return Text(
"Message 5",
style: [Link](context).[Link]!.copyWith(
color: [Link](context).[Link],
),
);
}
}

How we can apply the theme:


Output:
Let's break down these lines:

### Code Breakdown:


```dart
color: [Link](context).[Link],
child: Text(
'Text with a background color',
style: [Link](context).[Link]!.copyWith(
color: [Link](context).[Link],
),
),
```

1. **`color: [Link](context).[Link],`**:
- **`[Link](context)`**: This fetches the current `ThemeData` from the closest `Theme`
ancestor in the widget tree. The `ThemeData` contains all the styling information defined in
the app's theme.
- **`[Link]`**: Within the `ThemeData`, `colorScheme` is an instance of
`ColorScheme` which holds a set of 13 colors that can be used in an app. `primary` is one of
these colors, typically used for key UI elements such as the app bar or buttons.
- **Result**: This line sets the background color of the `Container` to the primary color
defined in the theme.

2. **`child: Text('Text with a background color',`**:


- This line creates a `Text` widget as a child of the `Container`, displaying the string 'Text
with a background color'.

3. **`style: [Link](context).[Link]!.copyWith(color:
[Link](context).[Link])`**:
- **`[Link](context).[Link]!`**: This fetches the `bodyMedium` text
style from the current theme's `TextTheme`. The `bodyMedium` style is typically used for
medium-sized body text.
- **`.copyWith(color: [Link](context).[Link])`**: The `copyWith`
method is used to create a copy of the `bodyMedium` text style with some modifications.
Here, it modifies the text color.
- **`color: [Link](context).[Link]`**: This sets the text color to
`onPrimary`, a color from the `ColorScheme` that is meant to be used on top of the
`primary` color (to ensure good contrast and readability).
- **Result**: The text inside the `Text` widget will use the `bodyMedium` text style, but
with its color set to `onPrimary`.

### Summary:
- The `Container`'s background color is set to the primary color from the theme.
- The `Text` widget inside the `Container` displays text using the `bodyMedium` style from
the theme, with its color set to `onPrimary` to ensure it contrasts well against the primary
background color.
Add interactivity to our app
Please visit URL to understand working of these controls : [Link]

Material Components

 Checkbox
 DropdownButton
 TextButton
 FloatingActionButton
 IconButton
 Radio
 ElevatedButton
 Slider
 Switch
 TextField

Drag and Drop


[Link]

Input & Forms


Create and style a text field:
import 'package:flutter/[Link]';

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

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter a search term',
),
)),
));
}
}

Output:

Retrieve the value of a text field

import 'package:flutter/[Link]';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Retrieve Text Input',
home: MyCustomForm(),
);
}
}

// Define a custom Form widget.


class MyCustomForm extends StatefulWidget {
const MyCustomForm({[Link]});

@override
State<MyCustomForm> createState() => _MyCustomFormState();
}

// Define a corresponding State class.


// This class holds the data related to the Form.
class _MyCustomFormState extends State<MyCustomForm> {
// Create a text controller and use it to retrieve the current value
// of the TextField.
final myController = TextEditingController();

@override
void dispose() {
// Clean up the controller when the widget is disposed.
[Link]();
[Link]();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Retrieve Text Input'),
),
body: Padding(
padding: const [Link](16),
child: TextField(
controller: myController,
),
),
floatingActionButton: FloatingActionButton(
// When the user presses the button, show an alert dialog
containing
// the text that the user has entered into the text field.
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
// Retrieve the text the that user has entered by using
the
// TextEditingController.
content: Text([Link]),
);
},
);
},
tooltip: 'Show me the value!',
child: const Icon(Icons.text_fields),
),
);
}
}

Output:
Handle changes to a text field

import 'package:flutter/[Link]';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Retrieve Text Input',
home: MyCustomForm(),
);
}
}

// Define a custom Form widget.


class MyCustomForm extends StatefulWidget {
const MyCustomForm({[Link]});

@override
State<MyCustomForm> createState() => _MyCustomFormState();
}

// Define a corresponding State class.


// This class holds data related to the Form.
class _MyCustomFormState extends State<MyCustomForm> {
// Create a text controller and use it to retrieve the current value
// of the TextField.
final myController = TextEditingController();

@override
void initState() {
[Link]();

// Start listening to changes.


[Link](_printLatestValue);
}

@override
void dispose() {
// Clean up the controller when the widget is removed from the
widget tree.
// This also removes the _printLatestValue listener.
[Link]();
[Link]();
}

void _printLatestValue() {
final text = [Link];
print('Second text field: $text (${[Link]})');
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Retrieve Text Input'),
),
body: Padding(
padding: const [Link](16),
child: Column(
children: [
TextField(
onChanged: (text) {
debugPrint('FIRST: First text field: $text ($
{[Link]})');
},
),
TextField(
controller: myController,
),
],
),
),
);
}
}

Manage focus in text fields


import 'package:flutter/[Link]';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Text Field Focus',
home: MyCustomForm(),
);
}
}

// Define a custom Form widget.


class MyCustomForm extends StatefulWidget {
const MyCustomForm({[Link]});

@override
State<MyCustomForm> createState() => _MyCustomFormState();
}

// Define a corresponding State class.


// This class holds data related to the form.
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle, create the
FocusNode in
// the initState method, and clean it up in the dispose method.
late FocusNode myFocusNode;

@override
void initState() {
[Link]();

myFocusNode = FocusNode();
}

@override
void dispose() {
// Clean up the focus node when the Form is disposed.
[Link]();

[Link]();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Text Field Focus'),
),
body: Padding(
padding: const [Link](16),
child: Column(
children: [
// The first text field is focused on as soon as the app
starts.
const TextField(
autofocus: true,
),
// The second text field is focused on when a user taps the
// FloatingActionButton.
TextField(
focusNode: myFocusNode,
),
],
),
),
floatingActionButton: FloatingActionButton(
// When the button is pressed,
// give focus to the text field using myFocusNode.
onPressed: () => [Link](),
tooltip: 'Focus Second Text Field',
child: const Icon([Link]),
), // This trailing comma makes auto-formatting nicer for build
methods.
);
}
}

Build a form with validation


import 'package:flutter/[Link]';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {


const MyApp({[Link]});

@override
Widget build(BuildContext context) {
const appTitle = 'Form Validation Demo';

return MaterialApp(
title: appTitle,
home: Scaffold(
appBar: AppBar(
title: const Text(appTitle),
),
body: const MyCustomForm(),
),
);
}
}
// Create a Form widget.
class MyCustomForm extends StatefulWidget {
const MyCustomForm({[Link]});

@override
MyCustomFormState createState() {
return MyCustomFormState();
}
}

// Create a corresponding State class.


// This class holds data related to the form.
class MyCustomFormState extends State<MyCustomForm> {
// Create a global key that uniquely identifies the Form widget
// and allows validation of the form.
//
// Note: This is a GlobalKey<FormState>,
// not a GlobalKey<MyCustomFormState>.
final _formKey = GlobalKey<FormState>();

@override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: [Link],
children: [
TextFormField(
// The validator receives the text that the user has
entered.
validator: (value) {
if (value == null || [Link]) {
return 'Please enter some text';
}
return null;
},
),
Padding(
padding: const [Link](vertical: 16),
child: ElevatedButton(
onPressed: () {
// Validate returns true if the form is valid, or false
otherwise.
if (_formKey.currentState!.validate()) {
// If the form is valid, display a snackbar. In the
real world,
// you'd often call a server or save the information
in a database.
[Link](context).showSnackBar(
const SnackBar(content: Text('Processing Data')),
);
}
},
child: const Text('Submit'),
),
),
],
),
);
}
}

Navigation and Routing


Working with Tabs:
import 'package:flutter/[Link]';

void main() {
runApp(const TabBarDemo());
}

class TabBarDemo extends StatelessWidget {


const TabBarDemo({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
title: const Text('Tabs Demo'),
),
body: const TabBarView(
children: [
Text("Car"),
Text("Bus"),
Text("Cycle")
],
),
),
),
);
}
}

Output:

Navigate to new screen and back:


import 'package:flutter/[Link]';

void main() {
runApp(const MaterialApp(
title: 'Navigation Basics',
home: FirstRoute(),
));
}

class FirstRoute extends StatelessWidget {


const FirstRoute({[Link]});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('First Route'),
),
body: Center(
child: ElevatedButton(
child: const Text('Open route'),
onPressed: () {
[Link](
context,
MaterialPageRoute(builder: (context) => const
SecondRoute()),
);
},
),
),
);
}
}

class SecondRoute extends StatelessWidget {


const SecondRoute({[Link]});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Second Route'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
[Link](context);
},
child: const Text('Go back!'),
),
),
);
}
}

Output:
Navigation with CupertinoPageRoute

In Flutter you are not limited to Material design language, instead, you also have
access to Cupertino (iOS-style) widgets

import 'package:flutter/[Link]';

void main() {
runApp(const CupertinoApp(
title: 'Navigation Basics',
home: FirstRoute(),
));
}

class FirstRoute extends StatelessWidget {


const FirstRoute({[Link]});

@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('First Route'),
),
child: Center(
child: CupertinoButton(
child: const Text('Open route'),
onPressed: () {
[Link](
context,
CupertinoPageRoute(builder: (context) => const
SecondRoute()),
);
},
),
),
);
}
}

class SecondRoute extends StatelessWidget {


const SecondRoute({[Link]});

@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: const CupertinoNavigationBar(
middle: Text('Second Route'),
),
child: Center(
child: CupertinoButton(
onPressed: () {
[Link](context);
},
child: const Text('Go back!'),
),
),
);
}
}

Output:
Send a string to a new screen

import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(title: 'Passing Data', home: DataSender()),
);
}

class DataSender extends StatelessWidget {


const DataSender({[Link]});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Send Data'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
String data =
"This is some data!"; // Replace with your desired
string
[Link](
context,
MaterialPageRoute(
builder: (context) => DataReceiver(data: data),
),
);
},
child: const Text('Send'),
),
),
);
}
}

class DataReceiver extends StatelessWidget {


final String data;

const DataReceiver({[Link], required [Link]});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Received Data'),
),
body: Center(
child: Text(
'You sent: $data',
style: const TextStyle(fontSize: 20.0),
),
),
);
}
}

Send a string to new screen using RouteSettings


import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(title: 'Passing Data', home: DataSender()),
);
}

class DataSender extends StatelessWidget {


const DataSender({[Link]});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Send Data'),
),
body: Center(
child: Column(
mainAxisAlignment: [Link],
children: [
ElevatedButton(
onPressed: () {
String data = "This is some data!"; // Replace with
your desired string
[Link](
context,
MaterialPageRoute(
builder: (context) => const DataReceiver(),
settings: RouteSettings(arguments: data),
),
);
},
child: const Text('Send'),
),
],
),
),
),
);
}
}

class DataReceiver extends StatelessWidget {


const DataReceiver({[Link]});

@override
Widget build(BuildContext context) {
final args = [Link](context)!.[Link] as String;

return Scaffold(
appBar: AppBar(
title: const Text('Received Data'),
),
body: Center(
child: Text(
'You sent: $args',
style: const TextStyle(fontSize: 20.0),
),
),
);
}
}

Send data shown in a list to a new screen

import 'package:flutter/[Link]';

void main() {
runApp(
MaterialApp(
title: 'Passing Data',
home: TodosScreen(
todos: [Link](
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
),
),
),
);
}

class Todo {
final String title;
final String description;

const Todo([Link], [Link]);


}

class TodosScreen extends StatelessWidget {


const TodosScreen({[Link], required [Link]});
final List<Todo> todos;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
body: [Link](
itemCount: [Link],
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the
DetailScreen.
// Notice that you're not only creating a DetailScreen,
you're
// also passing the current todo through to it.
onTap: () {
[Link](
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo:
todos[index]),
),
);
},
);
},
),
);
}
}

class DetailScreen extends StatelessWidget {


// In the constructor, require a Todo.
const DetailScreen({[Link], required [Link]});

// Declare a field that holds the Todo.


final Todo todo;

@override
Widget build(BuildContext context) {
// Use the Todo to create the UI.
return Scaffold(
appBar: AppBar(
title: Text([Link]),
),
body: Padding(
padding: const [Link](16),
child: Text([Link]),
),
);
}
}

Send data shown in a list to a new screen using RouteSettings

import 'package:flutter/[Link]';

class Todo {
final String title;
final String description;

const Todo([Link], [Link]);


}

void main() {
runApp(
MaterialApp(
title: 'Passing Data',
home: TodosScreen(
todos: [Link](
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
),
),
),
);
}

class TodosScreen extends StatelessWidget {


const TodosScreen({[Link], required [Link]});

final List<Todo> todos;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
body: [Link](
itemCount: [Link],
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// When a user taps the ListTile, navigate to the
DetailScreen.
// Notice that you're not only creating a DetailScreen,
you're
// also passing the current todo through to it.
onTap: () {
[Link](
context,
MaterialPageRoute(
builder: (context) => const DetailScreen(),
// Pass the arguments as part of the RouteSettings.
The
// DetailScreen reads the arguments from these
settings.
settings: RouteSettings(
arguments: todos[index],
),
),
);
},
);
},
),
);
}
}

class DetailScreen extends StatelessWidget {


const DetailScreen({[Link]});

@override
Widget build(BuildContext context) {
final todo = [Link](context)!.[Link] as Todo;

// Use the Todo to create the UI.


return Scaffold(
appBar: AppBar(
title: Text([Link]),
),
body: Padding(
padding: const [Link](16),
child: Text([Link]),
),
);
}
}

Return data from a screen

import 'package:flutter/[Link]';

void main() {
runApp(
const MaterialApp(
title: 'Returning Data',
home: HomeScreen(),
),
);
}

class HomeScreen extends StatelessWidget {


const HomeScreen({[Link]});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Returning Data Demo'),
),
body: const Center(
child: SelectionButton(),
),
);
}
}

class SelectionButton extends StatefulWidget {


const SelectionButton({[Link]});

@override
State<SelectionButton> createState() => _SelectionButtonState();
}

class _SelectionButtonState extends State<SelectionButton> {


@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: const Text('Pick an option, any option!'),
);
}

// A method that launches the SelectionScreen and awaits the result


from
// [Link].
Future<void> _navigateAndDisplaySelection(BuildContext context) async
{
// [Link] returns a Future that completes after calling
// [Link] on the Selection Screen.
final result = await [Link](
context,
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);

// When a BuildContext is used from a StatefulWidget, the mounted


property
// must be checked after an asynchronous gap.
if (![Link]) return;
// After the Selection Screen returns a result, hide any previous
snackbars
// and show the new result.
[Link](context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text('$result')));
}
}

class SelectionScreen extends StatelessWidget {


const SelectionScreen({[Link]});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pick an option'),
),
body: Center(
child: Column(
mainAxisAlignment: [Link],
children: <Widget>[
Padding(
padding: const [Link](8),
child: ElevatedButton(
onPressed: () {
// Close the screen and return "Yep!" as the result.
[Link](context, 'Yep!');
},
child: const Text('Yep!'),
),
),
Padding(
padding: const [Link](8),
child: ElevatedButton(
onPressed: () {
// Close the screen and return "Nope." as the result.
[Link](context, 'Nope.');
},
child: const Text('Nope.'),
),
)
],
),
),
);
}
}
Add a drawer to a screen

import 'package:flutter/[Link]';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {


const MyApp({[Link]});

static const appTitle = 'Drawer Demo';

@override
Widget build(BuildContext context) {
return const MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
}
}

class MyHomePage extends StatefulWidget {


const MyHomePage({[Link], required [Link]});

final String title;

@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {


int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 30, fontWeight: [Link]);
static const List<Widget> _widgetOptions = <Widget>[
Text(
'Index 0: Home',
style: optionStyle,
),
Text(
'Index 1: Business',
style: optionStyle,
),
Text(
'Index 2: School',
style: optionStyle,
),
];

void _onItemTapped(int index) {


setState(() {
_selectedIndex = index;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text([Link]),
leading: Builder(
builder: (context) {
return IconButton(
icon: const Icon([Link]),
onPressed: () {
[Link](context).openDrawer();
},
);
},
),
),
body: Center(
child: _widgetOptions[_selectedIndex],
),
drawer: Drawer(
// Add a ListView to the drawer. This ensures the user can
scroll
// through the options in the drawer if there isn't enough
vertical
// space to fit everything.
child: ListView(
// Important: Remove any padding from the ListView.
padding: [Link],
children: [
const DrawerHeader(
decoration: BoxDecoration(
color: [Link],
),
child: Text('Drawer Header'),
),
ListTile(
title: const Text('Home'),
selected: _selectedIndex == 0,
onTap: () {
// Update the state of the app
_onItemTapped(0);
// Then close the drawer
[Link](context);
},
),
ListTile(
title: const Text('Business'),
selected: _selectedIndex == 1,
onTap: () {
// Update the state of the app
_onItemTapped(1);
// Then close the drawer
[Link](context);
},
),
ListTile(
title: const Text('School'),
selected: _selectedIndex == 2,
onTap: () {
// Update the state of the app
_onItemTapped(2);
// Then close the drawer
[Link](context);
},
),
],
),
),
);
}
}

Create a login page in flutter

import 'package:flutter/[Link]';

void main() => runApp( MaterialApp(home: LoginPage()));


class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login'),
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [[Link], [Link]],
begin: [Link],
end: [Link],
),
),
),
),
body: Center(
child: Container(
padding: [Link](20.0),
child: Column(
mainAxisAlignment: [Link],
children: <Widget>[
// App Logo (Optional)
// [Link]('path/to/your/[Link]'),
SizedBox(height: 20.0),
// Username Field
Container(
decoration: BoxDecoration(
border: [Link](color: [Link]),
borderRadius: [Link](10.0),
),
child: Padding(
padding: [Link](horizontal: 10.0),
child: TextField(
decoration: InputDecoration(
hintText: 'Username',
),
),
),
),
SizedBox(height: 10.0),
// Password Field
Container(
decoration: BoxDecoration(
border: [Link](color: [Link]),
borderRadius: [Link](10.0),
),
child: Padding(
padding: [Link](horizontal: 10.0),
child: TextField(
decoration: InputDecoration(
hintText: 'Password',
suffixIcon: Icon(Icons.visibility_off),
),
obscureText: true,
),
),
),
SizedBox(height: 20.0),
// Login Button
Container(
width: [Link], // Match parent width
child: ElevatedButton(
onPressed: () {
// Handle Login Button press
},
child: Text('Login'),
),
),
SizedBox(height: 10.0),
// Forgot Password Text (Optional)
Row(
mainAxisAlignment: [Link],
children: <Widget>[
TextButton(
onPressed: () {
// Handle Forgot Password press
},
child: Text('Forgot Password?'),
),
],
),
],
),
),
),

);
}
}
Output:

You might also like