<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yasamin Yaldaei</title>
    <description>The latest articles on DEV Community by Yasamin Yaldaei (@yasaminyaldaei).</description>
    <link>https://dev.to/yasaminyaldaei</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F651065%2Ff0387f46-1cbb-4692-8f1d-37b5cbcc2b72.jpeg</url>
      <title>DEV Community: Yasamin Yaldaei</title>
      <link>https://dev.to/yasaminyaldaei</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yasaminyaldaei"/>
    <language>en</language>
    <item>
      <title>Collapsible header using the React Native Animated API</title>
      <dc:creator>Yasamin Yaldaei</dc:creator>
      <pubDate>Thu, 17 Jun 2021 09:50:37 +0000</pubDate>
      <link>https://dev.to/yasaminyaldaei/collapsible-header-using-the-react-native-animated-api-46dj</link>
      <guid>https://dev.to/yasaminyaldaei/collapsible-header-using-the-react-native-animated-api-46dj</guid>
      <description>&lt;p&gt;Here we're going to build an animated header that &lt;strong&gt;disappears when the user scrolls down the list and reappears when the user scrolls back upwards.&lt;/strong&gt; Also, the header will have a &lt;strong&gt;sticky bar&lt;/strong&gt; that will be there all the way around, no matter where the user is in the vertical list.&lt;/p&gt;

&lt;p&gt;This effect is pretty standard and commonly used in mobile apps.&lt;/p&gt;

&lt;p&gt;Without further ado, let's start the tutorial:&lt;/p&gt;

&lt;h2&gt;
  
  
  Container Component
&lt;/h2&gt;

&lt;p&gt;Here we will go with a classic approach. &lt;strong&gt;Putting the header component out of the scroll container and position it with &lt;code&gt;absolute&lt;/code&gt; style property.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This will cause an overlap between the header and scrollable content. So the &lt;code&gt;Animated.ScrollView&lt;/code&gt; will need a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contentContainerStyle={{paddingTop: this.state.headerHeight}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Therefor we need to measure the &lt;code&gt;headerHeight&lt;/code&gt; as well. For this to happen, we will pass an &lt;code&gt;onLayout&lt;/code&gt; callback function to the header component and will call it inside &lt;code&gt;CollapsibleHeader&lt;/code&gt; component later on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;onHeaderLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;headerHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
     &lt;span class="nx"&gt;headerHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// A bunch of code we don't need yet&lt;/span&gt;
&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// A bunch of components and props again not needed yet...&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CollapsibleHeader&lt;/span&gt;
  &lt;span class="c1"&gt;// A ton of props we don't care about yet...&lt;/span&gt;
  &lt;span class="nx"&gt;onLayout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onHeaderLayout&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;..&lt;/span&gt;
  &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to trace the scroll, we will use this function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;onScroll&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Animated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="na"&gt;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;contentOffset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollY&lt;/span&gt;&lt;span class="p"&gt;}}}],&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;useNativeDriver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which &lt;code&gt;scrollY&lt;/code&gt; is an &lt;code&gt;Animated&lt;/code&gt; value defined at the top of the container component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Animated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can check out the completed container component &lt;a href="https://gist.github.com/yasaminyaldaei/7ceef4ad185065b1a796ab1f19ac0f17#file-home-js"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Collapsible Header Component
&lt;/h2&gt;

&lt;p&gt;Our &lt;code&gt;CollapsibleHeader&lt;/code&gt; component will need to know about the scroll value to work. Therefore we will add this prop to the component which is in the container component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;scrollY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;onLayout&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;Remember the &lt;code&gt;onLayout&lt;/code&gt; callback from the previous section? Here's where we're going to define the function itself and fetch the required values and eventually inform the parent about it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;onLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;layoutHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLayout&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we will pass this function as a prop to the wrapper &lt;code&gt;Animated.View&lt;/code&gt; component, which navigates the animated transformation while scrolling the content.&lt;/p&gt;

&lt;p&gt;Next, we're fetching the height of the header component and putting it in the state to use later for transformation.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;diffClamp&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;Now, One of the crucial steps of achieving our desired animated effect comes to play: The &lt;code&gt;diffClamp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To understand what does this &lt;code&gt;Animated&lt;/code&gt; function does, let's start with clamping itself.&lt;/p&gt;

&lt;h4&gt;
  
  
  Clamping
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;In computer graphics, &lt;strong&gt;clamping&lt;/strong&gt; is the process of limiting a position to an area. In general, we use clamping to restrict a value to a given range.&lt;br&gt;
&lt;em&gt;Wikipedia&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The pseudocode for clamping is more intuitive to understand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function clamp(x, min, max):
    if (x &amp;lt; min) then
        x = min
    else if (x &amp;gt; max) then
        x = max
    return x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our case, &lt;code&gt;x&lt;/code&gt; would be the &lt;code&gt;scrollY&lt;/code&gt; value, obviously. But this simple clamping &lt;strong&gt;is not enough&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This function would only limit the exact &lt;code&gt;scrollY&lt;/code&gt; value. It would've been desirable to only display the header on the top of the page. And then hide it when the user scrolls past the header height.&lt;/p&gt;

&lt;p&gt;But what we want is to &lt;strong&gt;reappear the header when the user drags downwards and goes up on the list.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a way, we can say &lt;strong&gt;we don't care about the raw &lt;code&gt;scrollY&lt;/code&gt; value. We care about how much it's changed compared to a moment ago.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This functionality is what &lt;code&gt;diffClamp&lt;/code&gt; does for us. &lt;strong&gt;This function internally subtracts the two continuous &lt;code&gt;scrollY&lt;/code&gt; values and feeds them to the clamp function.&lt;/strong&gt; So this way, we will always have a value between &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;headerHeight&lt;/code&gt; no matter where on the list.&lt;/p&gt;

&lt;h4&gt;
  
  
  How to calculate the &lt;code&gt;diffClamp&lt;/code&gt;?
&lt;/h4&gt;

&lt;p&gt;We will calculate the &lt;code&gt;clampedScroll&lt;/code&gt; value in the &lt;code&gt;componentDidUpdate()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;componentDidUpdate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;scrollY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stickyHeaderHeight&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;layoutHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clampedScroll&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stickyHeaderHeight&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;layoutHeight&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;clampedScroll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;clampedScroll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Animated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;diffClamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;scrollY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;layoutHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;stickyHeaderHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So let's see what's going on here. Shall we?&lt;/p&gt;

&lt;p&gt;We set the &lt;code&gt;min&lt;/code&gt; value equal to &lt;code&gt;0&lt;/code&gt;. We want the calculations to start at the top of the list when the user has made no motion yet. And &lt;strong&gt;we stop the range when the user scrolls about the height of the header.&lt;/strong&gt; Since we want to display the sticky bar all the way around, &lt;strong&gt;we're subtracting the height of the bar here.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Fetch &lt;code&gt;stickyBarHeight&lt;/code&gt; in the &lt;code&gt;CollpsibleHeader&lt;/code&gt; component
&lt;/h4&gt;

&lt;p&gt;To get the sticky bar height, we've got several solutions. The solution used here exposes the &lt;code&gt;setStickyHeight&lt;/code&gt; method to the parent, and the parent passes it to the sticky bar component.&lt;/p&gt;

&lt;p&gt;Then this function gets called in the &lt;code&gt;TabBar&lt;/code&gt; component's &lt;code&gt;onLayout&lt;/code&gt; function eventually and gives us the height. We will go over this in more detail in the next section.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Another approach would be calling the &lt;code&gt;setStickyHeight&lt;/code&gt; method in the &lt;code&gt;ComponentDidUpdate()&lt;/code&gt; when the &lt;code&gt;stickyHeight&lt;/code&gt; prop is available through the parent.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rendering the animated header
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Phew!&lt;/em&gt; And we're done with clamping! So let's move forward to using what we've calculated. Now we're in the &lt;code&gt;render&lt;/code&gt; method finally!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We're going to change the &lt;code&gt;translateY&lt;/code&gt; value of the wrapper &lt;code&gt;View&lt;/code&gt;. Meaning moving it upward and downward.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We need a negative &lt;code&gt;translateY&lt;/code&gt; value equal to the &lt;code&gt;layoutHeight - stickyHeight&lt;/code&gt; to move it out of the view. And vice versa to display it again.&lt;/p&gt;

&lt;p&gt;The relationship between the &lt;code&gt;clampedScroll&lt;/code&gt; and the &lt;code&gt;translateY&lt;/code&gt; is equal but reverse in direction.&lt;/p&gt;

&lt;p&gt;So we just need to reverse the calculated clamped scroll value. Since we want to hide the header when the user scrolls down, (Thus, the &lt;code&gt;scrollY&lt;/code&gt; value increases). And we want to display the header as soon as the user scrolls up. (therefore decreasing the &lt;code&gt;scrollY&lt;/code&gt; value).&lt;/p&gt;

&lt;p&gt;And this is how it's done:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;translateY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;clampedScroll&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;layoutHeight&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;stickyHeight&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;Animated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clampedScroll&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Another approach would be using the &lt;code&gt;interpolate&lt;/code&gt; method.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping up
&lt;/h3&gt;

&lt;p&gt;And that's it! &lt;strong&gt;Now our animated value is generated and it's ready to be used.&lt;/strong&gt; All we need to do is to pass it in the &lt;code&gt;style&lt;/code&gt; array, alongside the &lt;code&gt;onLayout&lt;/code&gt; prop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Animated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt;
    &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;translateY&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;}]}&lt;/span&gt;
    &lt;span class="nx"&gt;onLayout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLayout&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Animated.View&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also since we use the &lt;code&gt;absolute&lt;/code&gt; positioning for the header component, we're going to use this container style:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;absolute&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;zIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can check out the completed collapsible header component &lt;a href="https://gist.github.com/yasaminyaldaei/7ceef4ad185065b1a796ab1f19ac0f17#file-collapsibleheader-js"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sticky Bar Component
&lt;/h2&gt;

&lt;p&gt;Now we're in the final step, which is writing the sticky bar component. Again, this component is an elementary one just to demonstrate the effect.&lt;br&gt;
In our case, this component will be the child of &lt;code&gt;&amp;lt;CollapsibleHeader&amp;gt;&lt;/code&gt; component. As such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CollapsibleHeader&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sectionTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;Awesome&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TabBar&lt;/span&gt; &lt;span class="nx"&gt;onLayout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onStickyHeaderLayout&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/CollapsibleHeader&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you see we only need to pass the &lt;code&gt;onLayout&lt;/code&gt; callback function of the parent. Which is similar to the one we've used for the &lt;code&gt;CollapsibleHeader&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;onStickyHeaderLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stickyHeaderHeight&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;stickyHeaderHeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;setStickyHeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stickyHeaderHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the second section, we've discussed the &lt;code&gt;setStickyHeight&lt;/code&gt; function of the &lt;code&gt;&amp;lt;CollapsibleHeader&amp;gt;&lt;/code&gt; and why we need it.&lt;/p&gt;

&lt;p&gt;To have the height, the main wrapper of the &lt;code&gt;&amp;lt;TabBar&amp;gt;&lt;/code&gt; component needs an &lt;code&gt;onLayout&lt;/code&gt; function which follows the same patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;onViewLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;onLayout&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;
  &lt;span class="nx"&gt;onLayout&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;onLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;You can check out the completed tab bar component &lt;a href="https://gist.github.com/yasaminyaldaei/7ceef4ad185065b1a796ab1f19ac0f17#file-tabbar-js"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  And finally
&lt;/h2&gt;

&lt;p&gt;We're good. We should have a smooth appearing/disappearing animation effect on our header component using the &lt;code&gt;Animated&lt;/code&gt; API.&lt;/p&gt;

&lt;p&gt;In the next post, we will create the same effect with a set of whole new tools! First, we will rewrite the components as Function components. Then, we will use some custom hooks. And above all, &lt;strong&gt;we will use the new and fancy Reanimated V2!&lt;/strong&gt;. Also, this time we will use the &lt;code&gt;interpolate&lt;/code&gt; approach.&lt;/p&gt;

&lt;p&gt;So if you've liked this one and are interested in the above topics, make sure to subscribe to my newsletter &lt;a href="https://yasaminyaldaei.com/react-native-animated-scroll/#newsletter"&gt;right here&lt;/a&gt; to be notified when the next post is shipped!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>reactnative</category>
      <category>react</category>
      <category>animation</category>
    </item>
  </channel>
</rss>
