Uber Eats Sticky Header - “Can it be done in React Native?”

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello react native developers what is going on I'm so glad we can put one in the books before the end of the year and this episode is all about mastering the classics so welcome to can it be done in Iraq native this week we are there are some snacks hello guys I hope you are well William here recording from you know it's beautiful Zurich Switzerland I hope you're having a great hand of the holiday and in this week's episode we're looking at the uber it's up and more specifically the scrollable header when you look at the restaurant so I can scroll through the menu here so there's a nice transition from the title of the menu at the below the image and the way it floats on the header when scoring further away and then when I reach some sections of the menu the tab translate nicely so scorable headers are a very common example requests of episodes for Canon billion relative and in deeds are really different kinds of configuration for scorable headers we've done one for Spotify this one is certainly quite sophisticated and very interesting I find this couple of things that caught my attention while doing while looking at this example so first of all you see that II the way the opacity of the tab transitions you cannot have a state of the gesture which is in between so you see that it's not completely driven by the scroll but rather the scrolling value drive drives should the tabs be visible or not and then it nicely transitions from the states but it's not the a value that drives a transition which I find to be pretty interesting and then we have this nice tabs which see goes from black the text goes from black to white which means that we're going to need to use some sort of fancy mask and thankfully now in react Nietzsche we can have such a mask working on both iOS and Android and so we have the title text but translate to the top of the menu so the whole thing is very very well orchestrated so how would we do it in react native well by looking at this example I see three layers the background layer which is the image and the image here is gonna scroll so the image is gonna translate to the same value and the scroll view and if the scroll value is negative on the US like this we're going to increase the height of the image proportionally so that's the background layer three layers the move layer in the middle is actually the scroll view with the content that was crawling here and you see the scouring indicator on the right and this content has some space at the top which is transparent so we can see is the image in the background and the third layer the layer at the foreground is this flood flow table header that we see here and it's opacity because when we reach the top goes from zero to one and it has some text miss mu Europe Ally which is always visible for any scrolling values and that translate nicely from whatever is the top of the menu to maximum this position so these are the three layers the flow tab is the flow table header on the foreground the scroll view as a middle layer and the background layer is the image so we are gonna listen to the Y animated value of the scroll view and use it to translate the text ear and transition the opacity so the opacity of the top tab bar is going to depend it's going to be 0 or 1 depending on the threshold value but you see it doesn't switch it switch very smoothly and we're going to use the we've transition functions which we introduced in the last video called 10-minutes react native transition so what when we reached when we reach the scoring threshold we are gonna transition from 0 to 1 and these functions are extremely useful really to decouple such animation problem where we don't have to think about all I need to you know time function to go from 0 to 1 and then if it scores back I need to cancel and so on no no we do there is a threshold the opacity goes from 0 to 1 and then in a separate step we use a transition function which was gonna nicely take care of transitioning from 0 to 1 1 to 0 according to a need that's also the same recipe we used in previous episodes a google chrome example where we move tabs around and the tabs are instantly switching from one position to the other and then we add a transition function so you see them nicely sliding from one position to the other so we do copper the problem in two paths so on the top header then we have this nice horizontal tabs and the way we're going to implement it is also again using a recipe we used already in the channel which is a masked view so these horizontal tab is again using three layers we have the black so the tab where the tabs where the text is black in the background we have the middle layer which is this black background button and this black background is animated according to the size of the text so for each tab we're going to measure the width of the tab using on layout so we can animate the weave of the of this black background and on top we have a masked view of so we have all the tabs written with white text and we use a tab we use a masked view so what you see we see this nice transition from one menu element to the other so that's a recipe we used already in the google chrome tabs the buttons I will link the video in the video description so that's a recipe we are going to use so I really like it because yeah there is really no new recipes we are going to implement the scroll bar header we've done this before with the specify example we're going to use transition functions to really enable the way we transition from the top header being visible or not and then we're going to use a mask view for the horizontal tabs so no no new recipes but really putting basically together everything that we know how to do transitions must view and dealing with a score view and then actually we have the content so these menu items and we're going to use only out to measure the position of these titles so for instance you have a beam price so I need to know when for which scoring value I need to switch to the bimba price if I tap on one item you see I Square to fry the chicken which means which is actually is no problem because if we use the square view we have really a bi-directional way to control the score view so we are going to get the Y value from the square view to animate or things but we can also set a reference to the square view and then I tap a button because I know I know to which position I need to scroll so I can use scroll to to scroll to the proper item when tapping a button but what do you guys think can it be done in react native let's have a look and before we get started one thing if you are looking to learn the fundamentals of declarative gestures and animations in react native I recommend you check out my online course at Star Trek native dev my girl with this course is to provide you with all the tools and knowledge necessary in order to build incredible user experiences that we run at 60fps even on low-grade Android device season if you follow this course I can promise you that all the examples we are doing in this can it be done in react native YouTube series should feel trivial and updating the course on a monthly basis right now we are doing a big chapter on SVG animations and we are bringing very very cool things and some incredible examples coming up so if you are interested to learn the fundamentals of gestures and animations in react native I recommend you check it out at start react native Devon all right guys let's get started yeah I have a boilerplate project which you can download from the video description in case you want to follow along with this example and so as it's a component which has the free layers I just mentioned earlier the header image in the background just called you with the content in the middle and the header on top and in the content component we do something quite interesting so we are is on measurement and call back and so we have the menu item eeeh yeah there are and some sections and what we do is that we use only out to measure the anchor so it's a y-value - the height of the header which we use to keep in the state so in the tab you see we have the name of the horizontal tab as well as the scrolling anchor so we know when we scroll to this position it's a threshold when we need to update the tabindex and by the cell when we tap on the horizontal horizontal tab we know we have to squirrel thanks to this anchor property so this really else and then we have the always internal tab which we have here which is again made of three layers which I mentioned earlier the tabs in the back which are written in black the view in the middle which is this black background view that you see here and the one on the foreground which has the active property to set the text to be white we which you see here so if I go to the tab you see we have color if it's active it's white and this is where we're going to use them as view to ensign in the Y animation value to animate everything properly but I suggest that we start first thing first we're gonna wrap square view into animated components so we can get the Y value and once we have the Y value are gonna start to animate things so let's let's go so animate is for view I'm gonna need to create Y animation value so my animation value because here you see every time we do on layout we have a rerender so we need to keep the Y animation value identity across rerun downs if you've been following the channel you know that we use use memo one in order to do that I know INRI - there is a convenience function to create his default animation value this particular different season which is called used values and use values Texas parameter an array of default animation value and you get on the array of animation value as return so it's going to be zero and you can set the dependencies like for user effect or like for use memo one and we can bind it to the on scroll event again here we have a helper from my - for that and you may need which we get from reanimated so it's n square so that looks good and first things first now we should have the Y value let's use the Y value 20 made the background image so let me save this file so yah now we receive Y as property which is an animated node so here we need to animate two things for this image the top property so it feels like it's gonna scroll exactly it's gonna be synchronized with the scorning of the content so it's gonna feel as if it's part of the same scroll view and then the ID when we scroll the scoring values around it gets even so let's start with let's start with the height so image becomes animated image because we're going to use animation values so right we're going to interpolate from the Y value so input fringe let's say minus 100 and output 0 so output range at 0 we know it's header image right and that minus 1 blood you know that it's header image ID plus 100 so it increases proportionally the ID and we know that it's only for negative squirting videos so we need to clamp on the right side so I'm going to write extrapolate write extrapolate clamp let's have a look I'm gonna add it to the style okay looks good now if I Square to the top the image needs to score as well so I'm gonna create the top so I'm gonna interpolate on the y value input range so we go from do we scroll not we don't so okay from zero to let's say 100 and output range is at zero top is at zero at 100 it's minus 100 and we extrapolate on the left side we'll clamp let's have a look looks good and it scores with the content perfect so now let's take care of the header so we're gonna pass the y-value to the header which is an animated odd and yeah we're going to use to animate three things the text Y and X translation so should be here on the x axis and y on the y axis when we had squaring position zero and if we scroll down is for score down to the content and then the clamped position on the right side should be this one yeah so translation zero on x and y let's start with translate y so translate y we interpolate on the y axis if we scrolled so input friend is if we score two header image right we know that output range is zero we know that we need to extrapolate on the right side with clamp and if we are at - no zero like we're image okay and if we had zero we should be at - at the right let's try I'm going to need to add the transform to the text so array of transformation translate why I'm having some okay I guess and we should remove their head height that looks good now let's do the so any clamps nicely now let's do the translate X so which again we interpolate on the y-axis so let me just copy this one input range at zero it should be - we've of this icon so at header image I'd it's zero that's good and that zero it should be - we've of this icon plus some edema so it should be minus I can size plus padded extrapolate should be clamped everywhere yes let's add it yeah so broke looks good now translates nicely we can do now the opacity yeah so we're gonna create a toggle value so is the audacity toggled or not again I'm gonna use use values default value is zero mean doesn't matter and I can type it as being its we know that it's your one use values it's we get from Ray - there's a dependencies parameter and we are gonna use a use code hook to set the toggle value so we're gonna set the toggle value and we need a dependency parameter and if condition so is toggle value great when so why is greater and had image right the opacity is gonna be 1 or 0 so it should be good I need to import these guys and so the interesting thing here I'm gonna bind for now opacity to toggle so we're gonna make sure the header opacity works great for this record value and wants this work we're going to use we've transitioned from Ray - it was a nice and smooth transition but is identical to the one from the bar it's so let's do that so I'm going to bind opacity to toggle and let me try to animate first the white background I'm going to address it yeah so it seems to work perfectly and now I can use i can create a viable the called transition and I'm gonna use the weave transition from real - I'm gonna bind the toggle I've heard you - it so with transition is using a default transition timing transition with deferred timing parameters you can use a spring transition if you want instead and you can customize the spring also timing animate transition parameters yeah I'm gonna use the default so I'm gonna use transition instead and so instead of abruptly switching from one to the other you see the white background switch which is nicely and let's do the opacity of the vertical tab and the arrow icon here let's do the tab opacity so I'm gonna pass transition as property transition which is an animated nod and the opacity here depends on this value okay so it looks good you see it nicely and you don't have a value for which this transition is not zero or one it's just nicely transitioning from one to the other it looks very very professional now let's do the let's do the icon color and then we will do the the article tab so yeah we have the black icon we're gonna overlay if I go down we're gonna overlay a white no we're gonna overlay ah the black are so we have white I cut the black one becomes is overlaid on top of the white one and becomes visible once the header is visible so I'm gonna use a absolute field to so it's gonna be animated you absolute field to overlay the icon and then we're gonna use opacity which we have here so animated you style so it's a style sheet absolute field object and opposite let's have a look so it's white and it transitions nicely to black perfect so now let's do the horizontal tab that we see here so we have our tabs we have the measurements so in the tabs component we use for each tab we use only out to measure the wheel of the tab so in the state we have the wave of each tab because we know that's the way we need to apply it to the black background which we have here and so you see here if you want these text to appear black we need to mask we need to mask this foreground tabs with this black background view so and luckily now we can use we can have you have mask view masked view for both iOS and Android which is a huge which I find I think it's a game changer for react natira to have this component no variable for for both platforms it used to be that we can only do it on iOS so I think it's really really amazing since these layers are overlaid on top of each other so this is done using an absolute fill it means I need also to really is amassed view using an absolute fill and the masked element mask a mask view we can import so masked view import from react native community masked view perfect so masked mask element so this is gonna be this one I mean I'm going to add animated view because we're gonna image this property but this is essentially a masked element let's a look so you see here perfect on the tabs of the foreground the white tabs only this part is masked which is exactly what we were trying to to do now let's animate when we reached so you see when I scroll here where these anchors values for his section titles and these we're gonna use to animate the width of this black background view and translate the tabs because it's always the selected tab is always on the left side so let's so we have the measurements so what we're going to do is create an animation value where I on the track the current index so I'm gonna it index we're gonna use that used to create it so it's gonna be a different value of number and default value is zero and now we're going to use use code to update the index based on the wires current value I need the depth depth parameter so I need the Y value which is an image node we need probably to pass it as a parameter here so we have the one animation value so we're going to use use code block dependencies now we are gonna map over each tab and we're gonna write a condition to set the index and the condition is so then we set index to I so I use index of the tab so we are tab I and the condition is if if Y is greater or equal of tab anchor and less than the next and less than Y is less than tabs the next tab anchor so tab I plus 1 dot anchor of course except if it's the only tab because there is no tabs plus 1 so in to check so this is if it's not the last tab so if it's the last tab it means that I equals tab dot length minus 1 and address needs to be greater or equal man tab and curl doing pot set clip some may have some syntax a are let's try to clean this up so that's the condition if the condition is true blog oops this looks correct okay so the index value here should be updated properly let's test it yeah by animating the weave of the black background which we're gonna interpolate from the Y value so we have weave sorry so which means a plate on the index value so we have input ranch we go from basically oil tab index of tabs map so we have tab index re tab index will turn index that's input range output range is already values measurements values let's see so yes starter starter order again gets bigger picked for you so it looks that it might be working in order to find out now we need to translate these items properly so we're going to calculate translate X which we're going to also interpolate on the index value input range is the same Orange now we need to add the sum of all the we've until the index until the index were currently at plus padding between the buttons so output range for each tab we need to do a reduce on the measurements to select all previous measurements so we have measurements we filled all the previous one and then do the sum and then we need also to remove so this is the translation value and we need also to remove the padding which is 8 pixels times index so first one is 0 index 1 we have 1 padding it's 8 16 and so on so here we filter 2 if so sorry G J so J is less than high so here we filter the proper measurements we need to do the some of these measurements and we're gonna do it using a red dress so it's gonna be accumulation yeah looks good accumulation plus value so it's gonna be act plus M and default value should be 0 syntax 0 minus 8 where is this tax our measurements filter okay and then there is translate X which we can apply to each tabs component so the two tabs components so I'm gonna wrap it into animated you again with an absolute position field and we're gonna put the translate X that you so start is absolute field object translate X and let's do it also for the one in the masked view syntax a all somewhere yes okay okay so you see here it switches abruptly but we can just add an transition to the index and so I'm gonna call it index transition and we're gonna use wave transition again here we use default value you can configure it to a spring timing animation and so we're gonna use it you have to animate the wheel and the translate X visa I find this new transition functions to be super powerful and you see it enables us to nicely animate from one value to the other I really love it it's very very cool and looks very professional so the fact that you see we so index treated as discrete value is the header opaque or not treated at discrete values just based on the scoring threshold and then we use transition to have like really smooth transition I think it's extremely wait it looks very professional I think it's it really shows how now we are really mastering these animation techniques to to beat these things very easily and so it looks pretty good I really like it and so the last so in its there is a bi-directional communication so yeah we have to scroll do what animates everything but we can also tap on the button potentially to scroll to a particular place and the square view does that very well because we can listen to the Y animation value and then it also provides a scroll to function which using which we can use when tapping a button so we can scroll to the proper content so we're gonna do that so we're gonna create a reference so scroll you use Ref it's an animated score view so we have ref squirrel you and we pass it as parameter to the header and then as parameter to the tab head so we receive it as parameter here and I think so it's a ref object and that's animated score view and we need to pass it down to this one same same story let me save files so score view we need to pass it down to the one in the background I think when we tap we probably actually tapping on the one that is invisible yes this one so if square view current we scroll review current get nod scroll to and why tabs at index anchor and I think we're just for safety because of pixel rounding we need to add one pixel to having some this one I can remove let's have a look okay we had some issue here with the value initialization the last one was selected first but although I'm a nut it seems to nicely switch to the proper values and if I tap yon picked for you it's selected nicely so you can go to picked for you go down go up pretty nice why at the start the first proper value is not correct so here we have a weird initialization the very first time is it because of the dependency with measurement I think so let's let's try sorry I'm going to try to add measurement is a as dependency index transition is index sorry about that yeah you see now because we set the proper dependency to index the initial value is correct so I really love these scrolling headers because so there was really different examples different configurations some are simple some are more complex this one is somewhat sophisticated but now we really have the tooling to to build this very nicely guys what was the last month or the year I hope you enjoyed it I'm so excited about the upcoming episode in the new year and I'm really looking forward to talk to you soon we're going to beat some incredible things together and in the meantime happy yakking
Info
Channel: William Candillon
Views: 67,177
Rating: undefined out of 5
Keywords: React, React Native, Can it be done in React Native?, JavaScript, TypeScript, gestures, animations, reanimated
Id: xutPT1oZL2M
Channel Id: undefined
Length: 43min 12sec (2592 seconds)
Published: Mon Dec 23 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.