2

So I am working on this react-native app, in this part I am working on a graph that look much like a calendar really you can scroll horizontally to see different days; you start by today on the very far right and you can scroll left to see previous days.

My issue is that as the user scroll to go left, the graph fetch more data and extend the size of the graph. and when it happens the day I am looking at get pushed and find my self looking to a different day as the graph size change.

I tried to have it scroll all the way to the top at every fetch, but that's not convenient at all.

I tried to make up some calculation and jump to the place where I am supposed to be looking, but that's not a good user experience to jump every time it fetch and the graph size change. I want to have a more user friendly experience.

Please let me know if my explanation is bad so maybe I can try to explain it better.

Thanks,

and that's how my code looks like



state = {
    filter: { startDate : new Date(new Date().setDate(new Date().getDate() - 2))}, 
    graphData: this.props.graphData
  };
var days;

  get initialScrollOffset(){
    const {startDate, endDate} = this.props
    const colCount = hourIntervals(this.state.filter.startDate, endDate).length
    const graphWidth = colCount * cellWidth
    const screenWidth = Dimensions.get('window').width
    //the 100 is to make up for padding and the left icons
    return screenWidth - graphWidth  + 100
  }

  componentDidMount() {
    setTimeout(() => {
      if(this.scrollView != null){
        this.scrollView.scrollToEnd()
      }
    }, 0.00001);
  }
  /**
   * Scroll all the way to the right of the ScrollView
   * This needs to be triggered at mount and again if the ScrollView changes size,
   * because its contents don't load all at once (if it's big).
   * This means there's some flicker and performance hit,
   * so we're only doing this on Android where contentOffset isn't supported
   * @returns {undefined}
   */

 androidAutoScroll = () => {
    if (Platform.OS === 'android' && this.scrollView) {
     this.scrollView.scrollToEnd()
    }
  }

  LastDaySummary

  render() {
    const {userData: userData} = this.props.graphData
    return (
      <View style={activityStyles.containerNoHorizontalPadding}>

        <Text style={activityStyles.h1}>Activity</Text>
        <View style={activityStyles.graphContainer}>
          <GraphRowIcons
            userData={userData}
          />

          <ScrollView
                horizontal
                contentOffset={{x: this.initialScrollOffset}}
                onContentSizeChange={this.androidAutoScroll}
                onMomentumScrollBegin = {(event) => {

               days += 10
               this.setState({filter: {startDate : new Date(new Date().setDate(new Date().getDate() - days))}}, ()=>{ //now fetching more days
               this.props.fetchGraphEvents(this.props.currentUser,  this.state.startDate)
               })

                  }
                }
              }
                ref={(scrollView) => { this.scrollView = scrollView }
                }
          >
            <GraphContentArea
              userData={userData}
              startDate={this.state.filter.startDate}//the graph is rendered starting from this date
              endDate={this.props.endDate}
            />
          </ScrollView>
        </View>
      </View>
    )
  }
}

1 Answers1

0

You can using onContentSizeChange event to handle the scroll offset after the content size is changed. Like

<ScrollView
  ref={ref => {this.scrollViewRef = ref;}}
  onScroll={this.onScroll}
  onContentSizeChange={this.onContentSizeChange}
>
  ... 
</ScrollView>

handleScroll = ({nativeEven}) => {
  this.scrollX = nativeEvent.contentOffset.x;
}

onContentSizeChange = (width, height) => {
  const newPositionX = this.scrollX - width - this.width;
  this.scrollViewRef.scrollTo({x: newPositionX, y: 0, animated: false});
  this.width = width;
}

This won't be so smooth, but will work.

P/s: I'm looking for smoothing solution also. Please update if you find one. Thank you

tuledev
  • 10,177
  • 4
  • 29
  • 49
  • Update: hi tuledev, thanks a lot for you help, to update you on this. I no longer get an error but when the new data get fetched I find myself at the very right of the graph, like in 0 –  Jan 14 '20 at 02:24
  • what does ref= means? it is possible to explain to me what's ref={ref => {this.scrollViewRef = ref;}} do? I am new to react native –  Jan 14 '20 at 04:52
  • ref={ref => {this.scrollViewRef = ref;}}. this line means we assign the scrollview to a reference is this.scrollViewRef. You can read more here https://facebook.github.io/react-native/docs/direct-manipulation, and here https://medium.com/@payalmaniyar/deep-understanding-of-ref-direct-manipulation-in-react-native-e89726ddb78e – tuledev Jan 15 '20 at 03:23