AMIR HARDON: OK.
Hi.
I'm Amir.
I work on Flutter.
And I'm going to talk about animation management
with Redux and Flutter.
And there's a talk about Redux tomorrow.
And I'm not going to go deeply into details
about how Redux works.
So if you're interested in that, I
encourage you to attend the Redux talk,
the application architecture talk tomorrow.
OK.
The first thing I will say is that there are many opinions
on how to do things out there.
And this is just one more suggestion.
So not a silver bullet, definitely.
OK.
I'm going to explain this idea by walking
through an example implementation of the "2048"
game.
Unfortunately, I don't have enough time
to explain the game.
So if you don't know the game, just
remember that the user picks a direction, left, right,
up, or down.
And all the tiles slide in that direction.
And some of them merge.
So this is how it looks when I swipe right.
The tiles slide to the right, and some tiles merge.
OK.
So we're going to implement this with a Redux architecture.
And this is a very typical Redux architecture
where the UI responds to user events
by dispatching actions to the store.
The store is where we manage our state.
And the store responds to actions by computing new states
and publishing these states back to the UI.
And we're going to represent the state for the game with a 4 x 4
integer matrix.
And we're implementing four mutation operations--
move left, right, up, and down.
Here, we see a unit test for the move right
operation, which is basically what you would expect.
This is how we set the gesture detector for our game board.
We basically say, when we detected a horizontal drag,
we just need to figure out what was that reaction, left
or right, and dispatch a move left or move right
action to the store.
This is the only thing that the UI is doing directly
in response to user events, dispatching actions
to the store.
The next thing we need to do is to wire our UI.
We get an update from the store with a new state,
and we need to show that on the screen.
Without animations, this is pretty straightforward.
We just get the state from the store update,
and we build a widget tree that shows the board for that state.
Animations makes this a little bit more complex.
And this is what I'm going to talk about.
So with animations the last state update
is no longer enough information to figure out
what we should be showing on the screen.
Given the rest state, we don't know
which transition we should be showing.
To deal with that, we can add more information
with our store updates.
So in addition to the current state,
we also include the previous state and the action
that's triggered the update.
So that triplet is enough information
to know which transition we should
be showing on the screen.
So this is a snippet from the build method of our board
widget.
We basically say, OK, we got this triplet from the store.
We got the new state, but we also
know the previous state and the last action.
And we're going to use that triplet
to build a new motion spec.
So this is the unit test for our build motion spec method.
And the motion spec is basically a description for which tile,
where it should be going, what it
should be doing on the screen.
The next problem we have to deal with are animation conflicts.
And an animation conflict is when a transition to state D
is triggered while the application is transitioning
between two other states.
I find it useful to differentiate between two
kinds of transition states.
Real ones are when the application is actually
waiting for something to happen, versus cosmetic transitions,
like the animation of the tiles sliding,
are just there to make the user experience more smooth.
So this is what our UI code is doing in response to a store
update.
It terminates any ongoing transition.
It figures out which transition it should be showing based
on the triplet it got from the store,
and it fires and forgets that transition.
Not exactly forget it, because we still
need a way to terminate it on the next store update.
So what happens when we get an animation conflict?
So here you see how it looks.
When I swipe left, everything is sliding.
And while it is sliding, I swipe down.
So what we get is this jump cut effect,
where the ongoing animation is terminated completely
immediately, and the next one starts.
And in this case, this is actually a decent solution.
So this actually feels responsive and natural
in this case.
And I argue that this is a decent fallback for most
or many cosmetic transitions.
So to get that fallback, the jump cut effect by default,
we need to make sure that our UI code keeps a promise.
And that promise is that, given that the last store update was
to state A, it is either showing state A
or showing a transition to state A.
Now, if you want more custom conflict resolution, something
more fancy than the jump cut effect,
you can still do that by managing more state
in the presentation layer in the UI.
Just make sure you still keep that promise.
So this was quite a lot to squeeze in five minutes.
So there's also a medium article with more details.
And the example code for the "2048" game
is available on GitHub.
Thank you.
[APPLAUSE]