Skip to content

This is an Example of a Flatlist in react native using scrollview and other FlatList features

Notifications You must be signed in to change notification settings

cosydney/flatlist_scrollview_rn

Repository files navigation

Note from the author: I remember struggling using FlatList when I started react native and this repo is an example of it using ScrollView with some clickable progress par footer.

Scrollabale form using React Native FlatList and ScrollTo method

copy paste the following in your terminal to see it in action :

git clone https://github.com/cosydney/flatlist_scrollview_rn.git && cd flatlist_scrollview_rn && npm install && yarn install && npm run ios

Gif example

App.js code:

import React from 'react';
import { StyleSheet,
Text,
Dimensions,
View,
FlatList,
Image,
TouchableHighlight,
TouchableOpacity } from "react-native";

const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;

class Footer extends React.Component {
  myscrollToIndex(index){
    if (this.props.reflist) {
      this.props.reflist.scrollToIndex({
        animated: true,
        index: index,
        viewPosition: 0.5});
    }
  };

  render() {
    steps = []
    superi = this.props.index
    myindex = 0
    this.props.form.map(function(item){
      if (item) {
        if (superi == myindex){
          steps.push({item: item, color: 'blue'})
        } else if (item.clicked) {
          steps.push({item: item,color: 'green'})
        } else {
          steps.push({item: item, color: 'grey'})
        }
        myindex++
      }
    })

    return (
      <View style={styles.footer}>
        <View style={[styles.footerLine, {width: 36*steps.length}]}></View>
        { steps.map(function(object, i){
            if (object.color == 'grey'){
              return(
                <View key={i}>
                  <TouchableOpacity key={i} onPress={() => this.myscrollToIndex(i)}>
                  <View style={[styles.dots, {backgroundColor: 'grey'}]}>
                  </View>
                  </TouchableOpacity>
                </View>)
            } else if (object.color == 'green') {
              return(
                <View key={i}>
                  <TouchableOpacity key={i} onPress={() => this.myscrollToIndex(i)}>
                  <View style={[styles.dots, {backgroundColor: 'green'}]}>
                  </View>
                    </TouchableOpacity>
                </View>)
            } else {
              return(
                <View key={i}>
                <View style={[styles.dots, {backgroundColor: 'steelblue'}]}>
                </View>
                </View>)
            }
          }, this)
        }
     </View>
    )
  }
}

class Form extends React.Component {
  state = {
    index: 0,
    update: true,
  };

  myscrollToIndex = () => {
    this.setState({index: this.state.index += 1});
    this.flatListRef.scrollToIndex({animated: true,index: this.state.index, viewPosition: 0.5},
    );
  };

  _finishFormVal = () => {
    //make some sort of validations here for all your answers
    alert('You finished this form and you are being redirected')
  }

  _changeStatus = (item) => {
    item.clicked ? item.clicked = false : item.clicked = true
    this.setState({update: !this.state.update}) // this signals Flatlist to rerender
  }

  _renderItem = ({item}) => {
    count = (this.props.form.length - 1) //will compare to index which is always 1 less
    return (
      <View key={item.id} style={[styles.flatListContainer, {backgroundColor: item.color}]}>
      <TouchableHighlight onPress={() => {this._changeStatus(item)}}>
        <View>
          <Text style={[styles.text, item.clicked ? {backgroundColor: 'green'} : {backgroundColor: 'grey'}]}>
            I am question {item.id + "\n"}
            Click on me to activate or disactivate me
          </Text>
        </View>
      </TouchableHighlight>

      <TouchableOpacity
      onPress={(count === this.state.index) ? this._finishFormVal : this.myscrollToIndex}
      style={styles.buttonNext}>
        <Text>Next</Text>
      </TouchableOpacity>
      </View>
    )
  }

  handleScroll = (event: Object) => {
    newindex = Math.floor(event.nativeEvent.contentOffset.y / height)
    this.setState({index: newindex})
  }

  _keyExtractor = (item, index) => item.id;

  render () {
    return (
      <View>
        <FlatList
          getItemLayout={(data, index) =>
            ({length:(height), offset: (height) * index, index}
          )}
          horizontal={false}
          ref={(ref) => { this.flatListRef = ref; }}
          scrollEnabled
          onScroll={this.handleScroll}
          keyboardShouldPersistTaps={"always"}
          data={this.props.form}
          extraData={this.props.form}
          keyExtractor={this._keyExtractor}
          renderItem={this._renderItem}
          keyboardDismissMode={'on-drag'}
          />
        <View style={styles.footer}>
            <Footer
              reflist={this.flatListRef}
              answers={this.props.answers}
              form={this.props.form}
              index={this.state.index}/>
        </View>
      </View>
    )
  }
}

export default class App extends React.Component {
  render() {
    formData = [
        {id: 1, color: 'skyblue', clicked: false},
        {id: 2, color: 'lightgreen', clicked: false},
        {id: 3, color: 'steelblue', clicked: false},
        {id: 4, color: 'green', clicked: false},
        {id: 5, color: 'powderblue', clicked: false},
        {id: 6, color: 'powderblue', clicked: false},
    ]
    return (
      <View style={styles.container}>
        <Form form={formData}/>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  centered: {
    display: 'flex',
    alignItems: 'center'
  },
  white: {
      backgroundColor: "white"
  },
  flatListContainer: {
    backgroundColor: 'green',
    flex: 1,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    height: height,
    overflow: 'visible',
    width: width,
  },
  footer: {
    height: 50,
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    flexDirection: 'row',
    backgroundColor: 'lightgrey',
  },
  footerLine: {
    position: 'absolute',
    height: 1,
    borderColor: 'darkgrey',
    borderWidth: 1,
    marginHorizontal: 40,
  },
  dots: {
    width: 20,
    borderRadius: 10,
    height: 20,
    margin: 13,
  },
  text: {
    paddingVertical: 20,
    paddingHorizontal: 30,
    textAlign: 'center'
  },
  buttonNext: {
    top: 250,
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: 50,
    width: 150,
    borderRadius: 75,
    backgroundColor: 'lightgrey'
  }
});

About

This is an Example of a Flatlist in react native using scrollview and other FlatList features

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published