12 Days of Baddass Courses sale! Get instant access to the entire egghead library of courses and lessons for 58% off.

Runs out in:
11 : 17 : 28 : 44
Join egghead, unlock knowledge.

Want more egghead? It's 58% off for a limited time only!

This lesson is for members. Join us? Get access to all 3,000+ tutorials + a community with expert developers around the world.

Unlock All Content for 40% Off
Become a member
to unlock all features

    Animate a React Native Information Callout View

    Jason BrownJason Brown
    react-nativeReact Native

    In this lesson we'll create a tap to show more information animation card. This is a great technique for exposing minimal information and then revealing more information if a user needs it. We'll use Animated.timing and rely heavily on interpolate to coordinating the sliding of the card, and scaling image animations. Finally we will need to disablethe ScrollView to allow for our gestures to work correctly.



    Become a Member to view code

    You must be a Member to view code

    Access all courses and lessons, track your progress, gain confidence and expertise.

    Become a Member
    and unlock code for this lesson




    We'll start by creating a scroll-enabled variable on state, and we'll set the default to true. Now, we'll set up a bind for a function we're about to create.

    So this.handleFocus=this.handleFocus.bind(this), which will be called when we want to focus on our callout and disable our scroll. We'll then set up our function by creating handleFocus, which will receive whether or not we've focused on the callout. We'll then say this.setState scrollEnabled to not focused.

    Now we'll go down to our scroll view, and set the scrollEnabled property to this.state.scrollEnabled, whenever we focus on our callout, the scrolling will not be able to go left to right, and if we press it again, then it will be enabled again.

    Finally, we'll also need to pass down the onFocus prop, and have it call this.handleFocus. Finally, we'll pass down the focus flag as a ! This.state.scrollEnabled.

    Now, I'll switch over to our moment file, then we'll set up our state, we'll say this.state is equal to an object with a scale, and create a new animated value with a default of 1, then, we'll do a bind for this.handlePress={this.handlePress.bind(this)} and create our handlePress function for later whenever the callout needs to be opened. Now, we'll create a componentWillMount lifecycle method and set up a few of our interpolations.

    The first will be this.backgroundFadeInterpolate, which will be equivalent to this.state.scale.interpolate, which will take our object and our input range, which will be .9 and 1, and output range, which will be rgba 000with an opacity of 03, and rgba 000with an opacity of 0The second will be our this.textFade which is equal to this.state.scale.interpolate with an input range of .9 and 1 as well, an output range of 0to 1.

    Finally, we'll need to set up our callout interpolate, say this.calloutTranslate=this.state.scale.interpolate with an input range of .9 to 1, and an output range of 0to 150.

    Now, we'll go set up our styles that are built on top of our interpolate, the first one will be our backgroundImage, which we'll say scale to this.state.scale, be sure we add a comma.

    Next, will be our backgroundFade style, which will be a backgroundColor and we'll pass in this.backgroundFade(interpolate).

    The second will be our textWillFade style equals opacity and this.state.textFade, and finally, our callout will be const calloutStyle=transform, which is an array of objects and our translate y, this.callout(translate).

    We'll wire up our touchable feedback, we'll say onPress=this.handlePress, then, we'll pass in the styles that we created, this one will be for our background wrap, which will be bgFadeStyle, and then another one will be for our middle text, which will be adding the textFade style that we created.

    Now, we'll create our callout that slides up, we'll start with an animated.view, inside of here, we'll write outOfView and then text with a style={styles.title} and this.props.title, that's getting passed down. Then for our animated view, will give it style equals an array of styles, one will be styles.callout, and the second will be calloutStyle that will translate our view up and down.

    We'll go down to our styles, and we'll create a new style which we'll call callout, allow a height of 150, a backgroundColor of 000with a .5 opacity, that will center its content, and be absolutely positioned.

    We'll scroll up to our handlePress and do animated.timing, and animate this.state.scale, pass in our object, and we'll say toValue of .9, because that's what our interpolations are based off of, with a duration of 300.

    We'll then call start, and inside our start, we'll say this.props.onFocus is true. If we go refresh our emulator, we can see that when we press on it, our callout slides up, our background scales to .9, our middle text disappears, and this slight black overlay happens.

    You'll also notice that if we try to scroll we cannot, because we've disabled our scroll with this this.props.onFocus call to true. If the callout is pressed again, then, we'll need to reanimate back to the scale of 1 and enable scrolling.

    Let's say if this.props.focused, then, we'll say animated.timing(this.state.scale) to value of 1, duration of 300 again, and then our start will call it this.props.onFocus of false. We'll also need to set our return here, otherwise, our bottom animation will trigger, as well.

    Now if we go refresh our emulator, you can see that we can animate out, and then on a press again, we can animate back, and our scroll will start working again. We can do the same for each of the screens.