FlatList Sticky Header Example

This is a simple example of Sticky Headers in FlatList Component of ReactNative made with NativeBase and Create React Native App tool. Detailed Setup instructions can be found below.

Find Full Code here


Sticky Header

1. Aim

We aim to create a simple App that implements sticky headers as shown in the GIF above.

2. Installation

  1. Create React Native App: Use CRNA tool to create an App like this

    $ npm install -g create-react-native-app
    $ create-react-native-app my-app
    $ cd my-app/
    $ npm start
  2. NativeBase

    npm install [email protected] --save
  3. Configure dependencies

    react-native link

Note: additional steps are required to import fonts from native base. Refer to this

3. Setting Things Up

With all required Libraries installed, we can start with some real coding. In the root of your project create a folder src. Inside this folder we create a file by the name of StickyHeader.js.
Note: You might have some problems setting up the project due to version conflicts, make sure you use same versions as mentioned below in the package.json
By the end of all this your project structure and package.json file should look something like this.
StickyHeader Package

4. Making our List Component

In your StickyHeader.js inside src folder add the following code.
Code src/StickyHeader.js

import React from "react";
import { FlatList } from "react-native";
import { Text, ListItem, Left, Body, Icon, Right, Title } from "native-base";
export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      data: [
        { name: "Movies", header: true },
        { name: "Interstellar", header: false },
        { name: "Dark Knight", header: false },
        { name: "Pop", header: false },
        { name: "Pulp Fiction", header: false },
        { name: "Burning Train", header: false },
        { name: "Music", header: true },
        { name: "Adams", header: false },
        { name: "Nirvana", header: false },
        { name: "Amrit Maan", header: false },
        { name: "Oye Hoye", header: false },
        { name: "Eminem", header: false },
        { name: "Places", header: true },
        { name: "Jordan", header: false },
        { name: "Punjab", header: false },
        { name: "Ludhiana", header: false },
        { name: "Jamshedpur", header: false },
        { name: "India", header: false },
        { name: "People", header: true },
        { name: "Jazzy", header: false },
        { name: "Appie", header: false },
        { name: "Baby", header: false },
        { name: "Sunil", header: false },
        { name: "Arrow", header: false },
        { name: "Things", header: true },
        { name: "table", header: false },
        { name: "chair", header: false },
        { name: "fan", header: false },
        { name: "cup", header: false },
        { name: "cube", header: false }
      ],
      stickyHeaderIndices: []
    };
  }
  componentWillMount() {
    var arr = [];
    this.state.data.map(obj => {
      if (obj.header) {
        arr.push(this.state.data.indexOf(obj));
      }
    });
    arr.push(0);
    this.setState({
      stickyHeaderIndices: arr
    });
  }
  renderItem = ({ item }) => {
    if (item.header) {
      return (
        <ListItem itemDivider>
          <Left />
          <Body style={{ marginRight: 40 }}>
            <Text style={{ fontWeight: "bold" }}>
              {item.name}
            </Text>
          </Body>
          <Right />
        </ListItem>
      );
    } else if (!item.header) {
      return (
        <ListItem style={{ marginLeft: 0 }}>
          <Body>
            <Text>{item.name}</Text>
          </Body>
        </ListItem>
      );
    }
  };
  render() {
    return (
      <FlatList
        data={this.state.data}
        renderItem={this.renderItem}
        keyExtractor={item => item.name}
        stickyHeaderIndices={this.state.stickyHeaderIndices}
      />
    );
  }
}

Explained

  • We import our FlatList component from ReactNative. Also we take care of a few other imports from NativeBase as we will require them further.
  • Next we are hard-coding our app data in our App state. Our data here just has a name and a boolean variable for header.
  • Next we fetch the indices of all the headers we would like to stick in our List. Notice how we have done that in the componentWillMount method.
  • In our render method, we have simply passed our FlatList Component with data provided. renderItem is called each time a new item appears in our List data.
  • keyExtractor prop is required to properly differentiate between data items using a unique key. We have used the names here.
  • stickyHeaderIndices will take an array of all the indices we want to stick. We pass the array we previously populated in 3.
  • Lastly, in the renderItem method we include a check for header items and children items. Accordingly we show different styles for each.

5. Finishing Up

We have successfully made our List component. Go ahead and include it in our App.js file. Build and run.

results matching ""

    No results matching ""