Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate listview items when they are added/removed from datasource

Tags:

react-native

Can someone give me an idea of how this can be done, e.g. animate the height from 0 when added and back to 0 when removed?

like image 433
David Avatar asked Aug 13 '15 19:08

David


3 Answers

Animation when added is easy, just use Animated in componentDidMount with your listRow , for example:

componentDidMount = ()=> {
    Animated.timing(this.state._rowOpacity, {
        toValue: 1,
        duration: 250,
    }).start()
}

Animate a component before unmount is much harder in react-native. You should set a handler for ListView. When dataSource changed, diff the data, start Animated to hide removed row, and set new dataSource for ListView.

like image 196
Fomahaut Avatar answered Nov 15 '22 19:11

Fomahaut


Here you can get full working example for opacity animation:

import React from 'react-native';

export default class Cell extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            opacity: new React.Animated.Value(0)
        };
    }

    componentDidMount() {
        React.Animated.timing(this.state.opacity, {
            toValue: 1,
            duration: 250,
        }).start();
    }

    render() {
        return (
            <React.Animated.View style={[styles.wrapper, {opacity: this.state.opacity}]}>
                <React.Image source={{uri: 'http://placehold.it/150x150'}} style={styles.image}/>
                <React.Text style={styles.text}>
                    Text
                </React.Text>
            </React.Animated.View>
        );
    }
}

const styles = React.StyleSheet.create({
    wrapper: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'flex-start',
        alignItems: 'center',
    },
    image: {
        height: 40,
        width: 40,
        marginRight: 16,
        backgroundColor: '#C9D5E6'
    },
    text: {
        fontSize: 20
    }
});
like image 24
neciu Avatar answered Nov 15 '22 17:11

neciu


In case you need for removing an item from the list, here's how to do the ListRow component:

class DynamicListRow extends Component {
   // these values will need to be fixed either within the component or sent through props
   _defaultHeightValue = 60;
   _defaultTransition  = 500;
   state = {
       _rowHeight  : new Animated.Value(this._defaultHeightValue),
       _rowOpacity : new Animated.Value(0)
   };
   componentDidMount() {
       Animated.timing(this.state._rowOpacity, {
           toValue  : 1,
           duration : this._defaultTransition
       }).start()
   }
   componentWillReceiveProps(nextProps) {
       if (nextProps.remove) {
           this.onRemoving(nextProps.onRemoving);
       } else {
// we need this for iOS because iOS does not reset list row style properties
           this.resetHeight()
       }
   }
   onRemoving(callback) {
       Animated.timing(this.state._rowHeight, {
           toValue  : 0,
           duration : this._defaultTransition
       }).start(callback);
   }
   resetHeight() {
       Animated.timing(this.state._rowHeight, {
           toValue  : this._defaultHeightValue,
           duration : 0
       }).start();
   }
   render() {
       return (
           <Animated.View
               style={{height: this.state._rowHeight, opacity: this.state._rowOpacity}}>
               {this.props.children}
           </Animated.View>
       );
   }
}

i've posted a complete tutorial to this question in this blog post. And it's explaining step by step what you need to do to accomplish both adding and removing an item and animate this process. For adding is pretty straight forward, but for removing looks like it's a little bit more complex. http://moduscreate.com/react-native-dynamic-animated-lists/

like image 2
alexmodus Avatar answered Nov 15 '22 17:11

alexmodus