Finding out scroll direction in react-native listview/scrollview
Asked Answered
D

2

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.

Driftage answered 20/4, 2016 at 14:50 Comment(0)
H
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);
Holloway answered 23/4, 2016 at 15:51 Comment(5)
Yup, just realized onScroll returns synthetic events :) Can you add the code here (in case rnplay goes down?) I'll accept it once soDriftage
If you are using ES6 classes, you will have to make sure your onScroll callback is bound to the component instance.Holloway
This used to work, but sometimes in iOS, the scroll direction changes when scroll ends the movement, to oposite direction.Bitner
There are some bug if you change the header visible above the scrollview,some time the direction gotten is opposite.Especially on android.Weaponry
How to get above functionality with hooks because with hooks how can we get this.offset .Alfonso
A
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;
  };
Abecedarian answered 30/6, 2017 at 19:49 Comment(1)
So Helpful and Simple!Norinenorita

© 2022 - 2024 — McMap. All rights reserved.