react native animated flatlist item after item

2019-05-15 12:05发布

问题:

I'm looking a way to make animated flatlist item after item. when one item finish his animation so next item(from the flatlist) will be on the screen

class AnimatedFlatList extends React.PureComponent {
    state = {selected: (new Map(): Map<string, boolean>)};
    let data = {[
        {"first_name":"ltorrejon0@si.edu"},
        {"first_name":"ichadbourne1@icq.com"},
        {"first_name":"ascorthorne2@mediafire.com"},
        {"first_name":"jlathwood3@xing.com"},
        {"first_name":"molkowicz4@ftc.gov"},
        {"first_name":"motridge5@tiny.cc"},
        {"first_name":"rcess6@hostgator.com"},
        {"first_name":"mmaundrell7@php.net"},
        {"first_name":"ufairburne8@instagram.com"},
        {"first_name":"pangel9@biglobe.ne.jp"}]
    };

    _keyExtractor = (item, index) => item.id;

    _onPressItem = (id: string) => {
        // updater functions are preferred for transactional updates
        this.setState((state) => {
            // copy the map rather than modifying state.
            const selected = new Map(state.selected);
            selected.set(id, !selected.get(id)); // toggle
            return {selected};
        });
    };

    _renderItem = (item) => (
        <View style={Styles.viewItem}}>
            <Text style={Styles.textItem>{item.text}</Text>
        </View>
    );

    render() {  
        return (
            <FlatList
                data={data}
                extraData={this.state}
                keyExtractor={this._keyExtractor}
                renderItem={this._renderItem}
            />
        );
    }
}

When I did animatedView into the renderItem it runs all together and it not what I'm looking for.

Kind of this way (but without press on the button, it will load automatically)

回答1:

Maybe there is a better solution but I am using the delay property of Animated.timing() and it works well for me.

My item component looks like this:

export default class CustomItem extends Component {

    constructor(props) {
        super(props);

        this.state = {
            scaleValue: new Animated.Value(0)
        }
    }

    componentDidMount() {
        Animated.timing(this.state.scaleValue, {
            toValue: 1,
            duration : 600,
            delay: this.props.index * 350
        }).start();
    }

    render() {
        return (
            <Animated.View style={{ opacity: this.state.scaleValue }}>
                { this.props.children }
            </Animated.View>
        );
    }
}

And here is the flatlist:

...
renderItem(item) {
    return (
        <CustomItem index={ item.index } >
            <Text>{ item.first_name }</Text>
        </CustomItem>
    );
}

render() {
    return (
        <FlatList
            keyExtractor={this._keyExtractor}
            data={data }
            renderItem={ this.renderItem.bind(this) }
        />
    );
}

So, every single item will delay 350 milliseconds more than the item before it.

Of course, you can change the duration of the animation and the delay property and find the perfect animation for you :)

You need to be careful with the number of the items because you can wait too much time to see the last item :)



回答2:

Checkout Animated.Stagger. Runs Animation parallelly but with successively specified delay.