Walrus
Walrus

Reputation: 20444

React Native, Dynamically adjust scrollIndicatorInsets of ScrollView / FlatList

Is it possible to change the values of scrollIndicatorInsets in React Native dynamically. I have tried doing this using a variable that is adjusted as the screen scrolls but am getting an invariant violation.

In the example below, the idea is to change the position of the top inset of the Scroll View as the user scrolls so that the scroll bar does not cover the header until that header has scrolled out of view.

Var set at Render

VSScroll = this.state.scrollY.interpolate({
            inputRange: [0, 88, 89],
            outputRange: [144, 88, 88]
        });

Return

<Animated.ScrollView
    scrollIndicatorInsets={[VSScroll, 0, 52, 0]}
    onScroll={Animated.event([
                    { nativeEvent: {
                    contentOffset: { y: this.state.scrollY }
                    }
                }],
                { useNativeDriver: true }
            )} >

... etc.

The variable VSScroll is causing an invariant violation even though console log checks show it is generating the number wanted to create the inset.

Upvotes: 0

Views: 2668

Answers (1)

Walrus
Walrus

Reputation: 20444

It is possible but scrollIndicatorInset will to work with the native scroll event. It will however accept a variable and therefore can accept a state.

So,

Create a state in the Constructor

this.state= {
    insetOffset: 140,
}

Add a listener to the onScroll Animated Event with it's own event bound to a function (eg. handleOnScroll)

onScroll={
    Animated.event(
        [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
        { 
            listener: (event) => this.handleOnScroll(event.nativeEvent.contentOffset.y), 
            useNativeDriver: true, 
        }
    )
}

Then use the function to return the desired value to the state. (Place the function between the Constructor and the Render.

handleOnScroll = event => {
        var offset = 140 - event;
        if(event > 98){
            offset = 140 - 98
        }
        this.setState({
            insetOffset: offset
        })
    }

Change the value of the scrollIndicatorInset to include the state

<Animated.ScrollView
    scrollIndicatorInsets={{top: this.state.insetOffset, left: 0, bottom: 52, right:0}}

QED..

Upvotes: 1

Related Questions