0% found this document useful (0 votes)
1 views

Unit - 4

This document covers Flutter forms and validation, detailing the creation of forms using widgets like Form() and TextFormField(), and the importance of managing state and disposing of resources. It also explains gesture handling through GestureDetector for various interactions, and outlines the navigation and routing system in Flutter, including the use of Route Generators for managing screen transitions. Additionally, it introduces Flutter animations, focusing on implicit animations and their implementation with examples.

Uploaded by

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

Unit - 4

This document covers Flutter forms and validation, detailing the creation of forms using widgets like Form() and TextFormField(), and the importance of managing state and disposing of resources. It also explains gesture handling through GestureDetector for various interactions, and outlines the navigation and routing system in Flutter, including the use of Route Generators for managing screen transitions. Additionally, it introduces Flutter animations, focusing on implicit animations and their implementation with examples.

Uploaded by

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

Unit - 4

Flutter Forms & Validation


Forms
A form consists of a series of fields (to be filled by the user with some information) that can be processed.

A typical example is a login form, in which the app generally could ask you for email and password. Once a
confirmation button in pressed, an HTTP request or another type of authentication process happens
Different functions to create form and validate

Form()
_formKey is used to uniquely identify the form and validate it later.

TextFormField() //Declaring controllers & Form Key


_nameController and _emailController manage the values inside text fields.

dispose()
dispose() is called when the widget is removed from the widget tree.
It frees up resources by disposing the controllers, which is important for
memory management.
Form submission()
This function is triggered when the user clicks the Submit button.
It checks if the form is valid (validate()).If valid, it shows a small notification
(SnackBar) and prints the entered data.

SnackBar()
If valid, it shows a small notification (SnackBar) and prints the entered data.
Steps to create a form

Step 1 : Importing Material Library


Step 2 : main() Function
Step 3 : MyApp Class
Step 4 : MyCustomForm Class//it creates the state object
Step 5 : _MyCustomFormState Class//Manges the state
Step 6 : Declaring Controllers and Form Key
Step 7 : Disposing Resources
Step 8 :Form Submission Logic//SnackBar
Step 9 :Building the Form
Code :
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Form Example',
home: Scaffold(
appBar: AppBar(
title: Text('Simple Form'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: MyCustomForm(),
),
),
);
}
}
class MyCustomForm extends StatefulWidget {
@override
_MyCustomFormState createState() => _MyCustomFormState();
}

class _MyCustomFormState extends State<MyCustomForm> {

final _formKey = GlobalKey<FormState>();


final TextEditingController _nameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();

@override
void dispose() {
_nameController.dispose();
_emailController.dispose();
super.dispose();
}
void _submitForm() {
if (_formKey.currentState!.validate()) {
// Process data
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Processing Data')),
);
print('Name: ${_nameController.text}');
print('Email: ${_emailController.text}');
}
}
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _nameController,
decoration: InputDecoration(labelText: 'Name'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your name';
}
return null;
},
),
TextFormField(
controller: _emailController,
decoration: InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your email';
}
if (!RegExp(r'\S+@\S+\.\S+').hasMatch(value)) {
return 'Please enter a valid email address';
}
return null;
},
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _submitForm,
child: Text('Submit'),
),
],
),
);
}
}
Gestures

Definition: Motion-based interactions like swiping, pinching, dragging, or long-


pressing.

Purpose: Allows for more natural or immersive interactions, often hidden or less
explicit.

Example: Swipe left to delete a message


Pinch to zoom on a photo
Long-press to open a context menu

Usage: Depends on user learning or familiarity with gesture-based controls.


Advantages:Can be faster or more fluid Saves screen space Offers advanced or
secondary functions
Flutter handles gestures using the class GestureDetector which has many
listeners ,such as:

 onTap,
 onDoubleTap,
 onLongPress,
 onVerticalDragStart,
 onVerticalDragEnd
Swipe to Dismiss
Gestures Detector

GestureDetector(
onDoubleTap: () {
print("Double tapped");
},
onLongPress: () {
print("Long pressed");
},
child: Container(
color: Colors.red,
width: 100,
height: 100,
),
)
Steps for Creating Gesture in Flutter
Step 1 : Importing Material Library
Step 2 : main() Function
Step 3 : MyApp Class
Step 4 : Gesture Example
Step 5 : Creating state class for Gesture
Step 6 : Create handleTap()
Step 7 : Use GestureDetector()
Step 8 : Make use of onTap()
Example for Gesture
Code :
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(
home: GestureExample(),
);
}
}
class GestureExample extends StatefulWidget {
@override
_GestureExampleState createState() => _GestureExampleState();
}

class _GestureExampleState extends State<GestureExample> {


String _message = 'Tap the box';

void _handleTap() {
setState(() {
_message = 'Box tapped!';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Gesture Example")),
body: Center(
child: GestureDetector(
onTap: _handleTap,
child: Container(
width: 150,
height: 150,
color: Colors.blue,
child: Center(
child: Text(
_message,
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center,
),
),
),
),
),
);
}
}
Tap Gestures
Callback Description
onTap Called when the user taps the widget.
Called when a pointer that might cause a tap has
onTapDown
contacted the screen.
onTapUp Called when a tap has occurred.
onTapCancel Called when the tap gesture was aborted.
onDoubleTap Called when the user double-taps.
onLongPress Called when the user presses for a long duration.
onLongPressStart Called when a long press gesture starts.
onLongPressMoveUpdate Called when the pointer moves during a long press.
Called when the user lifts their finger after a long
onLongPressEnd
press.
Called when the user releases the pointer after a long
onLongPressUp
press.
Drag Gestures (Pan)

Callback Description

onPanStart Called when a pan gesture starts.

onPanUpdate Called when the pointer moves during a pan.

onPanEnd Called when the user lifts their finger after a pan.

onPanCancel Called when the pan gesture is interrupted.


Horizontal Drag Gestures
Callback Description
onHorizontalDragStart Called when a horizontal drag starts.
onHorizontalDragUpdate Called when the pointer moves horizontally.
onHorizontalDragEnd Called when the drag ends.

Vertical Drag Gestures


Callback Description
onVerticalDragStart Called when a vertical drag starts.
onVerticalDragUpdate Called when the pointer moves vertically.
onVerticalDragEnd Called when the drag ends.
Scale/Pinch Gestures

Callback Description
onScaleStart Called when a scale gesture starts (pinch or zoom).
onScaleUpdate Called when the user changes the scale.
onScaleEnd Called when the scale gesture ends.

Force Press Gestures (iOS only, rarely used)


Callback Description
onForcePressStart Called when a force press is recognized.
onForcePressPeak Called when the force press reaches its peak.
onForcePressUpdate Called when the pressure changes.
onForcePressEnd Called when the force press ends.
Example for Multiple Gestures

GestureDetector(
onTap: () => print("Tapped"),
onDoubleTap: () => print("Double Tapped"),
onLongPress: () => print("Long Pressed"),
onPanUpdate: (details) => print("Panning: ${details.delta}"),
onScaleUpdate: (details) => print("Scaling: ${details.scale}"),
child: Container(
width: 150,
height: 150,
color: Colors.green,
),
)
Flutter Route Navigation
Organizing information across several screens is one of the most important
building blocks of any architecture.

In the Flutter world, your app’s pages are called routes, or screens, and they are
the equivalent of Activities in Android or ViewControllers in iOS.
Very intuitively, routes/ is going to contain all those UI widgets representing a route of the app.
Inside widgets/ we recommend putting all those reusable widgets that support the creation of your
app’s pages.

class FooterName extends StatelessWidget {


const FooterName();
@override
Widget build(BuildContext context) {
return Text("Your name",
style: const TextStyle(...)
);
}
}

Placing this code in widgets/footer_name.dart is very convenient because you know it’s an "utility"
piece of UI that will be reused across multiple pages as a footer. It can be integrated with const
FooterName() and a simple change on footer_name.dart is automatically reflected everywhere.
Steps for Navigation & Routing

1. Creation of Routes
2. The main.dart file (Setup the routes)
3. The routes.dart file
4. Navigation between the pages
5. Navigator 2.0
1.Creation of Routes

We’re going to create a simple application with two screens: HomePage, the
first route which appears when the app starts, and RandomPage, a route that
displays a random number at the center of the screen.
// Located in routes/random_page.dart
2. The main.dart file
Steps in main.dart file

1.This is the widget located at the root of the tree which has the task to setup
the various routes and redirect the user to the first page.
2. This is a string. We’re going to explain what is RouteGenerator in a moment;
it basically tells Flutter which is the first route that has to be loaded.
3. This is a method reference. The navigation between pages in Flutter works
like if you were using a browser. Each page has a name, which is like an "url" and
you show a page by "navigating" to that address
Route Generator

In Flutter, a Route Generator plays a central role in navigating between screens


(routes) in a structured and centralized way.
It allows you to define and manage all route transitions in one place, rather
than using Navigator.push(...) or MaterialPageRoute(...) throughout your code.

Purpose of a Route Generator :


Centralizes route definitions.
Handles dynamic routing based on settings.
Helps avoid hardcoded navigation logic scattered across the app.
Common Use Case
Instead of writing this multiple times:

Navigator.push(context, MaterialPageRoute(builder: (_) => HomePage()));

You define a generator and call:

Navigator.pushNamed(context, '/home');
3. The routes.dart file
There must be a route named '/' which has to map to the first page that’s being shown when
your app starts. It’s a requirement, not a just a good practice.

1. Actually this class is just a "wrapper" for a single static function because declaring global
functions is possible, but it’s not a good idea.generateRoute() is the main actor.

2. Each page of the app is uniquely identified by a string; it’s the same thing you’re used to
see on the internet where web pages are identified by URLs. In this case:
• The HomePage route is associated with the '/' path
• The RandomPage route is associated with the '/random' path
Do you want to press on a button and show the RandomPage widget? It’s very easy, you
just need to write...

Navigator.of(context)?.pushNamed(RouteGenerator.randomPage);

... and the new screen appears. The pushNamed() method takes a path, which is linked to
a page, and navigates to it; in this case it looks for '/random' and shows the widget that’s
been assigned to it.
4.Navigation between the pages

At this point, we have our routes properly set up inside routes.dart and we’re
ready to move
from one page to the other. A quick recap of the job we’ve done so far:
• creation of two routes called HomePage and RandomPage;
• setup of the routes in the MaterialApp() of main.dart;
• The creation of the RouteGenerator class which maps an URI to a widget so
that the
Navigator class can open routes
5. Navigator 2.0
Passing data between pages and widgets

Common use cases can be:

1. in a layout with many tabs, you need to pass data from a tab to another;
2. you have a route (a page) which has to send a primitive type or a complex
object to another route when navigating to it;
3. in the same page, two widgets need to exchange data.
Navigator Class
The Navigator class allows you to move from a route to another going back and
forth. The pages you navigate to are "overlapped" and the framework keeps
track of them using a stack.
How to use Navigator :

Navigator.of(context)?.pushNamed("/route_name")
Navigator.of(context)?.pop()

But there’s also another equivalent way to use them:

Navigator.pushNamed(context, "/route_name")
Navigator.pop(context)
Passing data with Navigator

We’re creating a simple to-do app; when an item of the list is tapped, a new
route appears with a description of the selected to-do.
In the first page, called TodosPage, we’re creating a list of Todos that are
displayed using a ListView.
When a to-do is tapped, a new route called InfoPage is opened to show the
description of the selected item.
Info page
Flutter Animations
Flutter animation refers to the process of adding motion and visual effects to
Flutter app’s UI components to enhance user experience.
Flutter provides a powerful and flexible framework for creating both simple and
complex animations.

Types of Flutter Animation

1.Implicit Animations
2.The animation library
3.Custom Animations
1.Implicit Animations
Easier to implement.
Use built-in widgets like AnimatedContainer, AnimatedOpacity, AnimatedAlign,
etc.
You just change a property, and Flutter animates the change for you.

Example :

AnimatedContainer(
duration: Duration(seconds: 1),
width: isExpanded ? 200 : 100,
height: 100,
color: Colors.blue,
);
Implicit animation in Flutter allows you to animate changes to a widget’s
properties with minimal code. Flutter handles the animation automatically
when the property changes.

Key Points :
Uses special animated widgets.
You specify a duration and the framework animates the transition.
No need for AnimationController or Tween.
Common Implicitly Animated Widgets:

AnimatedContainer
AnimatedOpacity
AnimatedAlign
AnimatedPadding
AnimatedPositioned
AnimatedCrossFade
AnimatedDefaultTextStyle
Steps for Implicit Animation
Step 1 : Import the Flutter material package
Step 2 : Main function - Entry Point
Step 3 : Root Widget (MyApp)
Step 4 : AnimationDemo Stateful Widget & State Class (_AnimationDemoState)
Step 5 : UI Build Method
Step 6 : Floating Action Button
AnimatedContainer - Example
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(home: AnimationDemo());
}
}
class AnimationDemo extends StatefulWidget {
@override
_AnimationDemoState createState() => _AnimationDemoState();
}

class _AnimationDemoState extends State<AnimationDemo> {


bool _isExpanded = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Implicit Animation')),
body: Center(
child: AnimatedContainer(
duration: Duration(seconds: 1),
width: _isExpanded ? 200 : 100,
height: 100,
color: _isExpanded ? Colors.blue : Colors.red,
curve: Curves.easeInOut,
child: Center(child: Text('Tap me')),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.play_arrow),
onPressed: () {
setState(() {
_isExpanded = !_isExpanded;
});
},
),
);
}
}
The animation library

Flutter provides a rich set of animation libraries built into the framework. These
are part of the flutter/animation.dart and flutter/widgets.dart packages,
giving you tools for both implicit and explicit animations.

Main Animation Libraries in Flutter :


1. Implicit Animation Library
2. Explicit Animation Library
3. Animation Curves
4. Physics-based Animation
5. Third-party Animation Libraries
1.Implicit Animation Library

Purpose: Animate property changes automatically.

Common Widgets (no need for AnimationController):

•AnimatedContainer

•AnimatedOpacity

•AnimatedAlign

•AnimatedPadding

•AnimatedPositioned

•AnimatedCrossFade

•AnimatedSwitcher

•AnimatedDefaultTextStyle
2.Explicit Animation Library
Used for fine-grained control over animations. Requires managing an
AnimationController.

Core Classes:
AnimationController
AnimationTween :
Animated.timing()
Animated.spring()
Animated.decay()
AnimatedBuilder
AnimatedWidget
AnimationController
In Flutter, the AnimationController is a core class used to manage animations.
It provides control over animation timing, including starting, stopping,
reversing, and repeating animations.

AnimationController({
required TickerProvider vsync,
Duration? duration,
double lowerBound = 0.0,
double upperBound = 1.0,
double value = 0.0,
})
AnimationTween :

1. Animated.timing()
Description: Animates a value over a set duration using easing functions.
Use case: Standard animations like fade, translate, or scale over time.

2. Animated.spring()
Description: Animates using spring physics. It creates a bouncy, natural
motion.
Use case: Buttons, popups, or any element needing "physical" feel.

3. Animated.decay()
Description: Starts with an initial velocity and gradually slows down to a stop.
Use case: Flick/swipe gestures, like when scrolling stops naturally.
3.Animation Curves

Curves define timing and easing of animations to make them feel natural.

Common Curves:
Curves.easeIn
Curves.easeOut
Curves.bounceIn
Curves.elasticOut
Curves.linearToEaseOut
Common Curves

1.Curves.easeIn
Description: Starts slow, then speeds up toward the end.
Use Case: Great for fade-ins, entering elements, or when you want to draw the user's
attention at the end of the motion.

2.Curves.easeOut
Description: Starts fast, then slows down at the end.
Use Case: Used for elements exiting, like sliding out panels or fading out text.

3. Curves.bounceIn
Description: Begins by bouncing before reaching the final value — it overshoots and
rebounds into place.
Use Case: Playful entry animations like buttons or emojis popping into view.
Behavior: The object appears to bounce as it enters.
4.Curves.elasticOut
Description: Overshoots its final position and then bounces back with an elastic
effect.
Use Case: Great for dramatic, elastic animations like popping UI elements or
bouncing balls.

5.Curves.linearToEaseOut
Description: Starts with a constant speed (linear) and then eases out (slows
down).
Use Case: Good for smooth transitions where speed consistency is needed
initially, like loading indicators or progress bars.
4.Physics-based Animation
Animations based on real-world physics such as springs, friction, or gravity.

Classes:
SpringSimulation
FrictionSimulation
BouncingScrollSimulation
DraggableScrollableSheet
AnimatedPhysics
SpringSimulation
simulates a spring using three key parameters:
mass: The mass of the object.
stiffness: How strong the spring is.
damping: How quickly the spring stops oscillating.
It's part of the Flutter physics engine (flutter/physics.dart), and typically used
with a Ticker or AnimationController
FrictionSimulation
It simulates an object that starts with a certain initial velocity and slows down
over time due to a drag (friction) factor.

FrictionSimulation(
double drag, // friction or resistance (typically between 0 and 1)
double position, // starting position
double velocity // initial velocity
)
BouncingScrollSimulation
In Flutter, BouncingScrollSimulation is a physics simulation that mimics the iOS-style
bouncy scrolling behavior when the user overscrolls a scrollable area.
It’s typically used under the hood by Flutter's scroll physics but can also be used
directly for custom simulations or animations.

BouncingScrollSimulation({
required double spring,
required double position,
required double velocity,
required double leadingExtent,
required double trailingExtent,
Tolerance tolerance = Tolerance.defaultTolerance,
})
DraggableScrollableSheet

in Flutter is a built-in widget that allows you to create a scrollable bottom sheet that
users can drag up and down. It’s great for features like bottom drawers, expandable
panels, or nested scroll views.
DraggableScrollableSheet(
initialChildSize: 0.3, // default visible height (30%)
minChildSize: 0.1, // minimum height (10%)
maxChildSize: 0.9, // maximum height (90%)
builder: (context, scrollController) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
boxShadow: [BoxShadow(blurRadius: 10, color: Colors.black26)],
),
child: ListView.builder(
controller: scrollController, // important!
itemCount: 25,
itemBuilder: (context, index) => ListTile(
title: Text('Item #$index'),
),
5.Third-party Animation Libraries
1. flutter_animate
•Chainable, declarative animations.
•Easy syntax: Text("Hi").animate().fade().scale()

2. lottie
•Render After Effects animations exported as JSON.

3. rive
•State machine-based, interactive animations.

4. simple_animations
•Simplified API for timeline-based complex animations.

5. animated_text_kit
•Animated text effects like typewriter, wave, fade, etc.
Custom Animations
• Creating custom animations in Flutter gives you full control over how widgets
animate—positions, sizes, opacity, colors, and more.

• Flutter offers a powerful animation framework based on the


AnimationController, Tween, Animation, and AnimatedBuilder.

• If we are looking for specific kinds of animations, such as 3D ones we go for


Custom Animations.
AnimationController: emits a certain range of values with a given frequency
in order to animate a widget.

Transform: scales, rotates, skews or alters the aspect of a widget using


matrices.

Stack: overlaps a series of children and allows custom positioning using the
Positioned widget.
Key Terms :
SingleTickerProviderStateMixin: Allows this state object to act as a
TickerProvider, which is required by the AnimationController (to manage frame
ticks efficiently).
late final: Means the variable will be assigned later (in initState) but only once.
_controller: Manages the animation's timing (start, stop, repeat, etc.).
vsync: this: Provides the ticker using the current class (which mixes in
SingleTickerProviderStateMixin).
Matrix4.skewY(0.1): Applies a vertical skew (shearing the widget slightly)..
rotateY(...): Chains a Y-axis 3D rotation (full circle over the animation).
value * 2π: Maps the 0–1 animation range to a full 360° rotation.
child: This is the unchanged Container
Steps for Custom Animation
Step 1 : Importing Material libraries
Step 2 : Main Function
Step 3 : Route Widget
Step 4 : DemoApp
Step 5 : Create state for DemoAppState(_DemoAppState)
Step 6 : Create initState()
Step 7 : call dispose()
Step 8 : For rebuild use - AnimatedBuilder()
Step 9 : use Transform()
Step 10 : Skew()
Step 11: Container()
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return MaterialApp(home: CustomAnimationDemo());
}
}
class DemoApp extends StatefulWidget {
@override
_DemoAppState createState() => _DemoAppState();
}
Sliding Animation
Key Terms :
_controller.status: This gets the current status of the animation (dismissed,
forward, reverse, or completed).

AnimationStatus.completed: This status means the animation has reached the


end (e.g., 1.0 if using a Tween from 0 to 1).

AnimatedBuilder: Rebuilds its child whenever the animation value changes.

_controller: Drives the animation progress (value from 0.0 to 1.0).

scale: Starts at 1.0 (normal size) and shrinks to 0.5 as animation progresses.
newPos: Starts at 20 pixels and moves up to 420 pixels diagonally (both X and Y).

You might also like