Hide TabNavigators and Header on Scroll

Viewed 12326

I want to hide the Header and the TabNavigator tabs onScroll. How do I do that? I want to hide them onScroll and show them on ScrollUp. My code:

import React, { Component } from 'react';
import { View, Text, ScrollView, StyleSheet, TouchableOpacity} from 'react-native';

class ScrollTest extends Component {

    render(){
    const { params } = this.props.navigation.state;

        return(
            <View style={styles.container}>

               <ScrollView>
                <View style={{styles.newView}}><Text>Test</Text></View>
                <View style={{styles.newView}}><Text>Test</Text></View>
                <View style={{styles.newView}}><Text>Test</Text></View>
                <View style={{styles.newView}}><Text>Test</Text></View>
                <View style={{styles.newView}}><Text>Test</Text></View>
                <View style={{styles.newView}}><Text>Test</Text></View>
                <View style={{styles.newView}}><Text>Test</Text></View>
                <View style={{styles.newView}}><Text>Test</Text></View>
               </ScrollView>

            </View>
        )
    }
}
const styles = StyleSheet.create({
  container:{
    flex:1, padding:5 
  },
  newView:{
     height: 200, backgroundColor:'green', margin:10
  }
})
export default ScrollTest;

I checked this link for Animated API but not able to figureout how to implement it in onScoll?

enter image description here

So the header HomeScreen and the tabs Tab1 and Tab2 should hide on scroll and show when scrolled up. How do I do that?

Please help getting started on this.

Many thanks.

2 Answers

I resolved for my case, hope this will be helpful

import React from 'react';
import {
  Animated,
  Text,
  View,
  StyleSheet,
  ScrollView,
  Dimensions,
  RefreshControl,
} from 'react-native';
import Constants from 'expo-constants';
import randomColor from 'randomcolor';

const HEADER_HEIGHT = 44 + Constants.statusBarHeight;
const BOX_SIZE = Dimensions.get('window').width / 2 - 12;

const wait = (timeout: number) => {
  return new Promise((resolve) => {
    setTimeout(resolve, timeout);
  });
};
function App() {
  const [refreshing, setRefreshing] = React.useState(false);

  const scrollAnim = new Animated.Value(0);
  const minScroll = 100;

  const clampedScrollY = scrollAnim.interpolate({
    inputRange: [minScroll, minScroll + 1],
    outputRange: [0, 1],
    extrapolateLeft: 'clamp',
  });

  const minusScrollY = Animated.multiply(clampedScrollY, -1);

  const translateY = Animated.diffClamp(minusScrollY, -HEADER_HEIGHT, 0);

  const onRefresh = React.useCallback(() => {
    setRefreshing(true);
    wait(2000).then(() => {
      setRefreshing(false);
    });
  }, []);

  return (
    <View style={styles.container}>
      <Animated.ScrollView
        contentContainerStyle={styles.gallery}
        scrollEventThrottle={1}
        bounces={true}
        showsVerticalScrollIndicator={false}
        style={{
          zIndex: 0,
          height: '100%',
          elevation: -1,
        }}
        onScroll={Animated.event(
          [{ nativeEvent: { contentOffset: { y: scrollAnim } } }],
          { useNativeDriver: true }
        )}
        overScrollMode="never"
        contentInset={{ top: HEADER_HEIGHT }}
        contentOffset={{ y: -HEADER_HEIGHT }}
        refreshControl={
          <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
        }>
        {Array.from({ length: 20 }, (_, i) => i).map((uri) => (
          <View style={[styles.box, { backgroundColor: 'grey' }]} />
        ))}
      </Animated.ScrollView>
      <Animated.View style={[styles.header, { transform: [{ translateY }] }]}>
        <Text style={styles.title}>Header</Text>
      </Animated.View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
  },
  gallery: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    padding: 4,
  },
  box: {
    height: BOX_SIZE,
    width: BOX_SIZE,
    margin: 4,
  },
  header: {
    flex: 1,
    height: HEADER_HEIGHT,
    paddingTop: Constants.statusBarHeight,
    alignItems: 'center',
    justifyContent: 'center',
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    backgroundColor: randomColor(),
  },
  title: {
    fontSize: 16,
  },
});

export default App;

checkout on Expo https://snack.expo.io/@raksa/auto-hiding-header

Related