ifelsething logoifelsething

How to Add a Sticky Header inside ScrollView in React Native

Published On: 2023-12-29
Posted By: Harish

In this post, we will add a sticky header to react native ScrollView which stays on top the screen even on scroll. First create a new react native project.

Create A New Project

Create a new react-native project by using npx. Check documentation for creating a new react native project.

npx react-native@latest init ReactNativeStickyHeaderScrollViewExample

Adding a basic ScrollView

Add ScrollView to app.tsx. If we use a single parent view, the contents of the view will scroll but if we want a view to stick, we have to add the sticky view outside of the main view.

//app.tsx
<ScrollView
      stickyHeaderIndices={[1]}
      style={styles.scrollView}
    >
      <View style={styles.block} />
      <View style={styles.header}>
        <TextInput
          placeholder="Search"
          style={styles.search_input}
        />
      </View>
      {
        list.length !== 0
        && list.map(m => {
          return item(m)
        })
      }
</ScrollView>

Here we can see that the search block is outside of list.map (main view) and its index is listed in stickyHeaderIndices array. For index, think of it as an array of views inside scrollview.

Final output will look like

test

Complete code,

//app.tsx

import {
  Text,
  TextInput,
  View,
  StyleSheet,
  ScrollView,
} from "react-native";

export const App = () => {
  const list = [...Array(4).keys()].map(m => m);
  const item = (i: number) => {
    return <View key={i} style={styles.item}>
      <Text style={styles.item_text}>
        {i}
      </Text>
    </View>
  };
  return (
    <ScrollView
      stickyHeaderIndices={[1]}
      style={styles.scrollView}
    >
      <View style={styles.block} />
      <View style={styles.header}>
        <TextInput
          placeholder="Search"
          style={styles.search_input}
        />
      </View>
      {
        list.length !== 0
        && list.map(m => {
          return item(m)
        })
      }
    </ScrollView>
  );
}

const styles = StyleSheet.create({
  scrollView: {
    flex: 1,
    backgroundColor: 'white'
  },
  block: {
    height: 200,
    marginBottom: 10,
    backgroundColor: 'tan'
  },
  header: {
    padding: 10,
    backgroundColor: 'white'
  },
  search_input: {
    padding: 10,
    fontSize: 15,
    borderWidth: 1,
    borderColor: 'lightgray',
    borderRadius: 50,
  },
  item: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    height: 300,
    padding: 10,
    borderWidth: 1,
    margin: 10,
    borderRadius: 10,
    borderColor: 'white',
    backgroundColor: 'lavender'
  },
  item_text: {
    color: "black",
    fontSize: 15,
    textAlign: "center",
  },
});

Share is Caring

Related Posts