Watermelon Messenger #1 — Tabbar Transitions using React Navigation, Reanimated, Gesture Handler

Victor K Varghese
5 min readNov 12, 2019

Performant animations in react native can be daunting to achieve. There are different ways to animate things in react native. Starting from Animated, we can use stuff like lottie-react-native, react-native-interactable, react-native-animatable.

Running everything on JS thread will result in performance bottlenecks, while using solutions like Lottie requires knowledge in exporting animations from AfterEffects as JSON.

react-native-gesture-handler and react-native-reanimated was introduced not so long ago. Both of them provide declarative animations which will work smoothly even if the JS thread is busy or blocked. When ever you see something dope in popular apps, most of us thinks about how we can do it in the frontend tech-stack we follow, will it be performant or an eye-sore ??

WhatsApp tab transition we need to build

Above you can see a fancy transition happening when going to camera screen. The way the screens and tab bar moves based on the swipe. Started with react-navigation, I was able to build a basic tab system. Now i need to figure out how to collapse the tabs while transitioning to camera screen. I did search for third party libraries that could be useful.

react-navigation-collapsible is one such library that help us collapse the header in react-navigation. But using this meant depending on the library too much. Luckily i was able to find snack from Github issues that did something similar, the snack contained code which changes color when the tabs change.

I was able to mode the snack and build something like the camera transition in WhatsApp, But there were bugs. I was able to use custom tabBarComponent which accepted position as a prop.

first draft

You can see that I interpolated the height directly to achieve this animation. But as you can see the header height change affected everything in the screen. Need to find a way to animate header without affecting the screen. I tried adding a static view which will act as a barrier to prevent the screen resize, But it messed up the camera screen.

width issue

Searching for more options ,i stumbled upon tabBarVisible, which can be used to disable tab-bar header . But as you can see below, not the best way to animate things. It was just getting disappeared not transitioning.

Then I thought of absolute positioning. I could keep the tab bar as an absolute view and animate the position instead of using height. Changing height had another problem when i defined views inside tab-bar, which resulted sticky animation with views crumbled inside Animated.View.

I was able to solve things by using the interpolate values in transformY keeping height constant. you can see the interpolate code below where for the first tab the output height is -18 tabBarHeight to completely hide the toolbar and for the others its a 0 to avoid any transform. Will tweak this in future to include support for collapsing toolbar someday.

final draft

And the result was great. The animations were smooth and as expected. You can see how the view transforms based on the screen transition. The height is n’t getting affected and view completely transforms in Y direction

When things started to get better, I decided to go full length and added

  • Indicator animations
  • Camera mount/unmount on screen focus
indicator code using reanimated

Its time to integrate react-native-camera and see how to mount/ unmount the camera when screen pops up. We need to make sure camera is turned off as soon as the screen loses focus, otherwise app is going to eat away all your CPU/memory.

withNavigationFocus is a higher order component which passes the isFocused prop into a wrapped component. It's useful if you need to use the focus state in the render function of your screen component or another component rendered somewhere inside of a screen.

camera mount/unmount

After adding proper design and following the specs, I was able to build something similar to WhatsApp.

final design

I was able almost all o features just using react-native reanimated, nothing else. Since these are optimised & native, everything is smooth.

TLDr : You can find the full code here

Stay tuned ….

I’m planning to integrate firebase, watermelonDB to build a complete messaging app that has different features.

“Remember, code is your house, and you have to live in it.”
Michael C. Feathers, Working Effectively with Legacy Code

Hey, I’m looking for part-time opportunities

Want to read more articles ?!

--

--

Victor K Varghese

Android | React Native Dev | Flutter Enthusiast! - Interested in part time opportunities