Create an Expanding Notify Input with Success Message in React Native

Jason Brown
InstructorJason Brown
Share this video with your friends

Social Share Links

Send Tweet
Published 7 years ago
Updated 5 years ago

In this lesson we'll create a notify button that expands from the middle to show a TextInput with a send button and once sent will hide the TextInput and show a thank you message. We'll use the helper method StyleSheet.absoluteFill to position our input inside of our wrapping View. This allows us to animate our TextInput and our messages in and out without effecting layout of each other. When pressed to show the TextInput and when we show the thank you message a combination of animating the width and justifyContent: "center" to make it appear as if we're animating the view from the center. We'll use Animated.timing and a success boolean on state to control what is rendered, and what is animating. interpolate will be used heavily to scale in and out views when they are needed.

[00:00] Let's dive in and check the state of our application before we start styling it and making it look nice. We have an animated value, as well as a Boolean for success of true and false, we have a handlePress, and we have a handleSend.

[00:15] Additionally, we have a few conditional inputs. If we're not successful, we'll render a text input, we'll also render the notifyMe text. However, if we are successful, we'll render a thank you message.

[00:31] The first thing we'll need to do is create an interpolation on the width so that we can control it expanding. We'll set up a const widthInterpolate, set this.state.animate.interpolate().

[00:46] Our input range will a few values, 05, and 1. This will give us three steps. We have an output range of 150, 150, and 300. We'll then also add an extrapolate:'clamp'. We'll then do const buttonWrapStyleWidth, then add our widthInterpolate.

[01:14] We can go ahead and apply that to our buttonWrap, refresh, and now we have a default of 150 width on our button. The input is currently visible, so we need to adjust it so it is scaled out of the way.

[01:31] Say const inputScaleInterpolate = this.state.animate.interpolate(). We'll set our input range to 05, and .6, so a three step, and our output range of 00and 1. We'll then set up inputScaleStyle which we have a transform of an array with a scale, and we'll put our inputScaleInterpolate in here.

[02:07] Now we can apply that to our interpolation, or to our input, and now when we refresh, we can see that it has scaled all of our stuff out of the way. Now we not only need to scale our input, but we also need to scale in our send button.

[02:25] We come up here and create a const sendButtonInterpolate = this.state.animate.interpolate(), and our input range will be slightly shifted, because we want it to animate in after our input has scaled in.

[02:45] We'll say input range, and we'll set it to 06, and 1, and our output range will be 00and then 1, so it will come in late. Now we can go in and set up our const sendButtonStyle, and do scale as well. Then we'll apply that to our sendButton.

[03:16] Finally, before we can actually see this in action, we need to create a scale for our notifyMe button. We'll say const notifyTextScaleInterpolate, we'll set up this.state.animate.interpolate(), and this we need to scale out quickly before we scale in anything else.

[03:40] We'll say our input range is a two-step of 0to .5, our output range is 1 to 0and we don't want to scale any further, so let's say extrapolate:'clamp'. Now we'll go ahead and set up const notifyTextStyle and this will also be a scale.

[04:03] We'll say transform scale and pass in this, and then we can apply this to our animated view that surrounds our text, so equals notifyTextStyle. Let's go up to our inputScaleInterpolate and we will add an extrapolate:'clamp' so it does not scale beyond 1.

[04:26] Now we'll go up here and say animated.timing, say this.state.animate to a value of 1, a duration of 300ms, and then we'll call start. Now when we press this button, our input expanded, focused, and our button scaled in.

[04:48] The final scale we'll need is for our thank you message. We want it to scale in as everything else is scaling out. What we'll do is set up a const thankyouScaleInterpolate = this.state.animate.interpolate(). With our input range we'll go from 0to 1, and our output range, we'll flip that around and go 1 to 0This will cause a revers effect, so once this is animating backwards from 1 to 0to reset, our scale will go from 0to 1 and it will look like our thank you is animating in. We'll say const thankyouTextStyle, do transform with a scale, and our thankyouScaleInterpolate, and well go apply this to our thankyouText.

[05:42] Now when we press the sendButton, handleSend will be called, so let's implement handleSend. We need to call this.setState, and say success is true, this will allow our thank you message to be shown, however it will be scaled out to 0because our animated value is all the way to 1 at the moment.

[06:13] Then, to scale everything out, we'll do an animated.sequence and in there, we'll say animated.timing = this.state.animate to value of 0duration of 300. We'll also do a delay of animated.delay of 1500 before we toggle everything back.

[06:41] We call start, start takes a function that we call once this animation is over, and at that point we're going to say this.setState success false to reset everything back to the beginning. Now if we refresh, click notify, type in an email, click send, everything expands back to nothing and then resets back to the notifyMe.

hj.park
hj.park
~ 4 years ago

Thank you for these nice tutorials. I've learned a lot how to use animation in many ways. In this tutorial, it shows the animation great when I click "notify me" but when I click the send button it gives me an error with "Style property 'width' is not supported by native animated module" I thought the problem is in handleSend function so I changed onPress function of send button to console log. However, it gives me a same error again. Would you mind if you let me know the reason?

Markdown supported.
Become a member to join the discussionEnroll Today