How-to make React Native lists bounce only from the bottom?
K

1

5

I'm using a FlatList with a consequent ListHeaderComponent as the root component of my screen. I don't want the top of it to bounce on scroll, but I want to keep the bottom bouncing for UX'n'feel purpose as the FlatList supports infinite scroll. Any ideas how-to?

Kalliekallista answered 2/8, 2017 at 20:51 Comment(0)
C
14

A solution would be to listen to scroll events and check whether the bounces prop inherited from ScrollView should be enabled or not. Note that I personally find this solution to be a bit of an overkill, but it works as expected.

You can find a fully working example at the following URL: https://snack.expo.io/SkL-L0knZ. You can preview it right in the browser and you can also try it on your mobile device with the Expo app.

Here is the result (forget about the lag, as this was captured in the browser):

react native scrollview bounces

And here is the relevant source code:

export default class App extends Component {

    constructor (props) {
        super(props);
        this.state = { bounces: false };
        this.renderHeader = this.renderHeader.bind(this);
        this._onScroll = this._onScroll.bind(this);
    }

    _onScroll (event) {
        const scrollPosition = event && event.nativeEvent && event.nativeEvent.contentOffset && event.nativeEvent.contentOffset.y;
        let newBouncesValue;

        if (scrollPosition < viewportHeight / 3) {
            newBouncesValue = false;
        } else {
            newBouncesValue = true;
        }

        if (newBouncesValue === this.state.bounces) {
            return;
        }

        this.setState({ bounces: newBouncesValue });
    }

    renderHeader () {
        const { bounces } = this.state;
        const style = [
            styles.header,
            { backgroundColor : bounces ? 'darkseagreen' : 'firebrick'}
        ];

        return (
            <Text style={style}>{ bounces ? 'CAN BOUNCE' : "WON'T BOUNCE"}</Text>
        );
    }

    renderItem ({item}) {
        return (
            <Text style={styles.row}>{item.key}</Text>
        );
    }

    render() {
        return (
            <View style={styles.container}>
                { this.renderHeader() }
                <FlatList
                    data={DUMMY_DATA}
                    renderItem={this.renderItem}
                    onScroll={this._onScroll}
                    bounces={this.state.bounces}
                    scrollEventThrottle={16}
                />
            </View>
        );
    }
}
Chinquapin answered 2/10, 2017 at 15:8 Comment(2)
wondering this would make an impact for performance as it updates stateBattiste
It will if you set the state every time the onScroll dispatch. However, you can control updating the state only if the condition change.Reflation

© 2022 - 2024 — McMap. All rights reserved.