Search code examples
reactjsreact-nativereact-native-flatlistreact-native-navigation

Make the Header scroll down with FlatList and Animated - React Native


I didn't find any soulotion to do animated with FlatList, I want to hide my Header when I scroll down like In Facebook app. I tried To use FlatList with diffClamp() without success, I don't know if I can do it with FlatList but I need also LazyLoading, Someone Can help me?

This is my Header:

import React, { useState } from "react";
import {
  View,
  Animated,
  Text,
  Dimensions,
  TouchableOpacity
} from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import { Ionicons } from "@expo/vector-icons";

const Header = props => {
  const params = props.scene.route.params;
  const [headerHeight] = useState(
    params !== undefined && params.changingHeight !== undefined
      ? params.changingHeight
      : Dimensions.get("window").height * 0.065
  );
  return (
    <SafeAreaView style={{ backgroundColor: "rgb(152,53,349)" }}>
      <Animated.View
        style={{
          width: Dimensions.get("window").width,
          height: headerHeight,
          flexDirection: "row",
          backgroundColor: "rgb(152,53,349)"
        }}
      >
        <TouchableOpacity
          onPress={() => {
            props.navigation.openDrawer();
          }}
        >
          <View
            style={{
              paddingVertical: "15%",
              justifyContent: "center",
              paddingHorizontal: 25
            }}
          >
            <Ionicons name="ios-menu" size={30} color={"white"} />
          </View>
        </TouchableOpacity>
        <View style={{ justifyContent: "center", marginLeft: "23%" }}>
          <Text
            style={{
              fontSize: 20,
              fontWeight: "bold",
              textAlign: "center",
              color: "white"
            }}
          >
            MyGameenter code here{" "}
          </Text>
        </View>
      </Animated.View>
    </SafeAreaView>
  );
};

export default Header;

This is my FlatLIst:

import React from "react";
import { View, FlatList, StyleSheet } from "react-native";

import { EVENTS } from "../data/dummy-data";
import Event from "./Event";

const renderGridItem = itemData => {
  return <Event item={itemData.item} />;
};

const ShowEvents = props => {
  return (
    <View style={styles.list}>
      <FlatList
        keyExtractor={(item, index) => item.id}
        data={EVENTS}
        renderItem={renderGridItem}
        numColumns={1}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  list: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  }
});

export default ShowEvents;

Solution

  • Use

    onScroll={(e) => console.log(e.nativeEvent.contentOffset.y)}
    

    Working Example: https://snack.expo.io/@msbot01/privileged-candies

    import React, { Component } from 'react';
    import { Text, View, StyleSheet, ScrollView, FlatList } from 'react-native';
    import Constants from 'expo-constants';
    
    export default class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          DATA: [],
          previous: 0,
          hide: false,
        };
      }
    
      componentDidMount() {
        var array = [];
        for (var i = 0; i < 100; i++) {
          var a = { id: i, value: i };
          array.push(a);
        }
        this.setData(array);
      }
    
      setData(a) {
        this.setState({
          DATA: a,
        });
      }
    
      Item({ title }) {
        return (
          <View
            style={{
              width: '100%',
              height: 30,
              marginTop: 5,
              backgroundColor: 'green',
              justifyContent: 'center',
              alignItems: 'center',
            }}>
            <Text />
          </View>
        );
      }
    
      _onScroll(event) {
        // console.log('>>>>>>>>>>>'+this.state.data);
        if (this.state.previous < event) {
          this.setState({
            hide: true,
            previous: event,
          });
        } else {
          this.setState({
            hide: false,
            previous: event,
          });
        }
    
        console.log(event);
      }
    
      render() {
        return (
          <View style={{ flex: 1 }}>
            {this.state.hide == true ? null : (
              <View
                style={{
                  width: '100%',
                  height: 50,
                  justifyContent: 'center',
                  alignItems: 'center',
                }}>
                <Text>Hide me while scrolling</Text>
              </View>
            )}
            <FlatList
              onScroll={e => this._onScroll(e.nativeEvent.contentOffset.y)}
              data={this.state.DATA}
              renderItem={({ item }) => (
                <View
                  style={{
                    width: '100%',
                    height: 30,
                    marginTop: 5,
                    backgroundColor: 'green',
                    justifyContent: 'center',
                    alignItems: 'center',
                  }}>
                  <Text />
                </View>
              )}
              keyExtractor={item => item.id}
            />
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({});