14.1 Interactivity and Gestures
# Dismissable
The Dismissable
widget is one that we can wrap around ListTile
widgets. It is used to swipe away things like ListTile
. The user can touch the ListTile
and slide their finger left or right to
reveal hidden controls behind the tile, like a delete IconButton
. It takes child:
, background:
, secondaryBackground
, and key: ValueKey(myString)
properties. The child will be your
ListTile
. The background
and secondaryBackground
properties will be the colours shown behind the ListTile
as the user swipes. It also includes the onDismissed: (direction) {}
property that
holds a handler function meant to call a setState(() => items.removeAt(i))
. The key property is needed because we are targetting widgets for removal.
The update of the state value can trigger the ListView
build method to recreate the children
of the ListView
. This recreates the new list of Dismissable
widgets that each hold a ListTile
.
Here is the Dismissable reference (opens new window).
Dismissable
When you create your ListView
, if you are using the ListView.builder()
, then the itemBuilder: (BuildContext context, int index) {}
property can return a Dismissable()
which contains the
ListTile
, or any other Widgets you want.
# GestureDetectors
Flutter has a GestureDetector
widget that is used to capture user interactions with the screen. You can wrap your other widgets with a GestureDetector
widget to accomplish the same sort of thing
that you did with addEventListener
in JavaScript.
GestureDetector widget
# MediaQuery
Flutter has an inherited widget called MediaQuery
that can be used to determine information about the device and screen dimensions. You can use the same approach as accessing ColorScheme properties.
Eg: Theme.of(context).colorScheme.primaryColor
.
The MediaQuery.of(context)
method will return a MediaQueryData
instance object.
var deviceInfo = MediaQuery.of(context);
//deviceInfo.size.width
//deviceInfo.size.height
//deviceInfo.padding
//deviceInfo.orientation
//deviceInfo.textScaler
//and more properties. See the MediaQueryData reference page.
2
3
4
5
6
7
The MediaQuery class gives us access to lots of properties that can be used as values for properties or in ternary statements to build alternate versions of a layout.
MediaQuery
Reference for the MediaQuery class (opens new window)
Reference for the MediaQueryData class (opens new window)
# Focusing on Widgets in Flutter
Here is a guide to understanding the focus system in Flutter (opens new window)
# Animation in Flutter
There are two kinds of animation in Flutter - Explicit and Implicit.
The Explicit ones use animation controllers. These give more control but are harder to set up.
The Implicit ones use custom or built-in widgets. These give slightly less control but are easier to set up.
Here is a list of the popular built-in Animation Widgets (opens new window)
This video by NetNinja (opens new window) walks through setting up a couple basic implicit animation widgets like AnimatedContainer()
and AnimatedOpacity()
. It is part of a playlist
for animation in Flutter.
This Tween video by NetNinja (opens new window) walks through setting up Tween animations. These are another type of animations that use a TweenAnimationBuilder()
widget
with defined starting and ending points.
Here is the official Flutter playlist for animations (opens new window).
# Animated List
When working with a ListView
widget we have the ListView.builder
constructor that allows us to feed in dynamic data while creating the List.
Another alternative to the ListView.builder
is to use an AnimatedList
which will add some smooth transitions when you dynamically add or remove items from your data list.
Reference for AnimatedList (opens new window). It also uses an itemBuilder
property.
AnimatedList widget
# Flutter Animate
There is a flutter_animate
(opens new window) package that makes it quite easy to add animations to your Widgets. Start by adding it to the pubspec.yaml file as a
dependency.
There are a couple ways that you can use this package. The first is to wrap your widget inside an Animate()
widget and pass it an array (List
) of effects
.
Container(
child: Animate(
effects: [FadeEffect(), SlideEffect()],
child: Text('Just a widget.'),
),
)
2
3
4
5
6
Alternatively you can chain together a series of methods, starting with the animate()
method.
Container(
child: Text('Just a widget.').animate().fade().slide(),
)
2
3
In either case, you can modify the animation steps from the default settings. All the effects have optional delay
, duration
, and curve
parameters. Effects run in parallel, but you can use a
delay to run them sequentially.
SizedBox().animate(
onPlay: (controller) {
//this function runs when animation starts
return controller.repeat()
})
.fade(duration: 600.ms)
.callback(duration: 600.ms, callback: (_){
//this runs 600ms after start of animation
})
.scale(delay: 600.ms, duration: 600.ms)
.move(delay: 300.ms, duration: 900.ms)
.then() //waits for preceding animations to complete
.blurXY(delay: 1200.ms)
2
3
4
5
6
7
8
9
10
11
12
13
In the above, the onPlay
property inside of animate
runs that function when the animation starts. The fade
, callback
, scale
, and move
are all triggered at the same time and only delay from
the initial start by the value of their delay
value. The then
method creates a delay that happens before the blurXY
is called.
All the methods have the delay
and duration
properties. Most of the methods also have additional properties. Eg: tint(tint: Colors.pink)
or
move(duration: 400.ms, begin: Offset(0,0), end: Offset(20, 20))
flutter_animate Widget of the Week
flutter_animate package on pub.dev (opens new window) flutter_animate API ref (opens new window)
# More Resources
Flutter Animation Cheatsheet (opens new window)
Net Ninja Flutter Animation Tutorial (opens new window) from Aug 2020. A little outdated but the majority of the concepts still apply completely.
G Skinner Flutter Animated library - (opens new window)
# What to do this week
TODO Things to do before next week
- Work on your Final Project