Page after page, you keep scrolling. Whether it's on your computer or your phone, a
lot is usually happening while you're scrolling. In React Native, it is important to know how you
can add side effects when the user scrolls down. In today's episode of How To Animated, let's
learn about animated events with scroll views. Here's the idea: we have a long scroll view
component, and whenever we scroll down to a certain point, a header should appear at the top of
the screen. When we go up again, it should disappear. To get started, I have created both the scroll view
and the header but for now, there is no animation. The way it works is by using the onScroll callback
on ScrollView, we can check whenever the vertical scroll position is higher than let's say 100
pixels, and if so, we show the header by changing the state headerShown, otherwise we put it back
to a hidden position. By the way, if you look at onScroll, you can see we're using contentOffset.y
to get the vertical scrolling, but this event contains a few other indicators in case you want
to do something different such as knowing the whole layout size or the content size. To animate
it, there are actually not so many changes to do. First, we import Animated and we need to create
an animated value that will hold the translation value for the header. Just to be clear, this value
will hold the vertical position so in this case, 0 or -100 and we're going to animate
this so it smoothly appears on the screen. By default, it's hidden so we'll set it to -100,
and it should be set as the translateY style property on the header, which
will become an Animated.View also. Alright, now all that is missing is to animate
the translation value based on state changes: when headerShown becomes true, the translation
should animate to 0, and when it's false, to -100. Let's start the
animation and the useEffect hook. Now the problem with this approach
is once again performance-related. In fact, with Animated, there is quite often a
way to animate views without using state at all. Not using state means things could happen
on the UI thread instead of the JavaScript one which is a boost for UI changes. Let's see
how we could do this in a more "Animated way". The way we could think of this problem is
the following: if we can store the vertical scroll value as an animated value, then we could
interpolate this value to either -100 when we're below 100 pixels, or 0 otherwise to show the
header. The major difference is that we'll keep track of the scrolling value at any time, and based
on this, we'll decide whether the header should be shown. But "talk is cheap, let's see the code" right?
To begin with, we'll create another animated value that will store the scrolling value. The idea
now is that when we scroll, this value should be updated. To do so, there is a very handy helper
called Animated.event which maps an animated value to an event value. Okay so I agree, the API
for this looks odd the first time, but you can see it as a deconstruction of the event object
usually passed through the onScroll callback. Here we say, map the scrolling animated value
to the nativeEvent.contactOffset.x event value. So whenever this value changes, Animated
will reflect this change on the animated value too. If i wanted to map scrolling to the
horizontal offset, I would need to change y to x. Again, I think it helps to think of it as a
deconstruction that we usually do in JavaScript. All it does is mapping a sub value from the
event to the animated value, that's it. By the way, if you're curious, under the hood Animated
calls setValue on the animated value whenever the event is fired. But instead of you doing it,
Animated handles it for you. Anyways, one last thing missing here is the second parameter which
holds the optional configuration for the event. Here, we need to mark it as using the native driver
to get the performance boost I mentioned earlier. And also, because onScroll is using an Animated
event, the ScrollView component needs to be turned into an animated one as well. So we'll
replace ScrollView with an Animated.ScrollView. Now since we won't be using the state to update
our header position, we can get rid of the side effect and the state itself. The only bit we're
left with is our vertical translation for the header. As I said, the idea is to interpolate
our scrolling value so that when we're past 100 pixels down, the header should be visible
and hidden otherwise. To do so, we can say, when scrolling is between 100 and 130 pixels, the
header should appear accordingly. Remember to clamp on both sides, since we want to keep it at
-100 before 100 pixels, and at 0 after 130. See? It works! Now, I have to say there's indeed one
difference with our first version which is that the scrolling is simply interpolated in this case.
In the previous example, we had a clear animation playing when the header visibility was set to
change. What you should remember here is that instead of the usual callback with onScroll and
a component state, we simply use animated values, with the scrolling one being mapped to the current
scrolling using Animated events. You could also for example interpolate the scrolling to background
color, going from a light one to darker tones when scrolling. It's all up to you! Okay now that you know
about scrolling animated events, let's wrap this up. If there are 3 things to remember today, here
they are. If set, onScroll gives us information on the current scrolling position and other
indicators (contentOffset, contentInset, contentSize...). To correctly change an animated value
based on a scrolling event, we use Animated.event with onScroll. Finally, all it needs is a mapping of
the event with the corresponding animated values, that will be changed on the UI thread whenever
the event is fired. Alright, that's it for now. In the next episode, we will look at a big topic,
gestures, following what we've learned today. Remember to subscribe if you
don't want to miss it. Thanks for watching,
and see you next time :)
This was a fantastic video - I saw how short it was and almost couldn't believe how well you'd packed the information into it. Excellent job! Subbed
amazing production quality, I left a comment on one of your post about a potential partnership let me know.
Wow amazing video, love the editing to focus on parts of code versus just someone typing all the code out.
Great video! Keep it up 👏
Great guide, i really enjoyed watching. keep it up!
Great video! I just went and watched the short series and can't wait for the next one. I like the style, very clean and easy to understand.
Clean! Good job
Does anybody here know where i can find the same content, but for native Android Development?