30

Is there a way to find out the scroll direction of react-native's listview/scrollview components?

Native iOS components seem to be able to do it by calculating the offset from scrollViewWillBeginDragging and scrollViewDidScroll, but there seems to be no bindings for these.

Secret
  • 3,291
  • 3
  • 32
  • 50

2 Answers2

59

You can use the onScroll event of a ScrollView and check the contentOffset in the event callback:

https://rnplay.org/apps/FltwOg

'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  ScrollView,
  Text,
  View,
} = React;

var SampleApp = React.createClass({
  offset: 0,
  onScroll: function(event) {
    var currentOffset = event.nativeEvent.contentOffset.y;
        var direction = currentOffset > this.offset ? 'down' : 'up';
    this.offset = currentOffset;
    console.log(direction);
  },
  render: function() {
    return (
      <View style={styles.container}>
        <ScrollView style={styles.scroller} onScroll={this.onScroll}>
          <Text>Scrollable content here</Text>
        </ScrollView>
      </View>
    )
  }
});

var styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: 50,
  },
  scroller: {
    height: 5000,
  },
});

AppRegistry.registerComponent('SampleApp', () => SampleApp);
alexp
  • 3,587
  • 3
  • 29
  • 35
  • Yup, just realized onScroll returns synthetic events :) Can you add the code here (in case rnplay goes down?) I'll accept it once so – Secret Apr 25 '16 at 04:28
  • If you are using ES6 classes, you will have to make sure your onScroll callback is bound to the component instance. – alexp Sep 15 '18 at 15:27
  • This used to work, but sometimes in iOS, the scroll direction changes when scroll ends the movement, to oposite direction. – Philip Enc May 13 '19 at 22:02
  • There are some bug if you change the header visible above the scrollview,some time the direction gotten is opposite.Especially on android. – Devin Gong Aug 13 '19 at 02:38
  • 2
    How to get above functionality with hooks because with hooks how can we get this.offset . – Hardik Desai Jul 13 '21 at 07:23
21

I had problems with alexp's solution to accurately specify the direction when the difference between the old and the new offset was very small. So I filtered them out.

  _onScroll = event => {
    const currentOffset = event.nativeEvent.contentOffset.y;
    const dif = currentOffset - (this.offset || 0);

    if (Math.abs(dif) < 3) {
      console.log('unclear');
    } else if (dif < 0) {
      console.log('up');
    } else {
      console.log('down');
    }

    this.offset = currentOffset;
  };
Johannes Filter
  • 1,863
  • 3
  • 20
  • 25