ListView动画问题



  • 想给ListView中每个Row添加一个点击动画,但renderRow时所有Row都使用了同一个state,如下
    <Animated.Image
    source={{uri: '“###”'}}
    style={[styles.image,{transform: [{scale: this.state.bounceValue}]}]}
    />
    导致每次点击所有Row都会有动画,有什么方案可以解决这个问题吗



  • 可以设置一个state来区分cell是否被点击,在cell设置style的时候用这个state判断是否使用带动画的style吧



  • 1、你可以在renderRow里渲染一个你自己的自定义组件,然后在其中初始化Animated对象
    2、renderRow时,在函数内初始化Animated.Value,以及操作它的回调函数,也可以。

    不过更推荐方法1



  • 啊,ListView的动画问题,也困扰我很久,不过搞定了现在
    要明白两点
    1,RN利用的是MVVM原理,数据驱动UI,这个要好好理解
    2,state的改变都会执行 render() 方法,改变UI,render就是re-render

    那我们就改变state里的数据就好了,然后在render里写好我们的UI变换逻辑

    给一段抛砖引玉的代码,点赞功能,+1,-1,并且有动画

    import {createAnimatableComponent,Text,View} from 'react-native-animatable';
    import Icon2 from 'react-native-vector-icons/FontAwesome'

    render(

    return

    <TouchableOpacity onPress={this.UP.bind(this,comment)}>
    {
    (comment.clicked)
    ? <View animation={comment.animation} duration={1000} style={{flexDirection:'row',}}>
    <Icon2 name={comment.FIsLiked?'thumbs-up':'thumbs-o-up'} size={20} style={{color:'gray'}} />

                                            <Text style={{color:'gray'}}>{comment.FNLike}</Text>
                                        </View>
                                    :   <View animation='rubberBand' delay={rowID*100+500} duration={1000} style={{flexDirection:'row',}}>
                                            <Icon2 name={comment.FIsLiked?'thumbs-up':'thumbs-o-up'} size={20} style={{color:'gray'}} />
                                          
                                            <Text style={{color:'gray'}}>{comment.FNLike}</Text>
                                        </View>
                            }
                           </TouchableOpacity>
    

    )

    UP点赞方法

    UP(comment){
        //dbComments是我单独维护的一个数据源
        let cc = dbComments.find((c)=>{return c.FID === comment.FID });
        if(!cc) return;
    
        if(!cc.clicked)  //model里并没有clicked这个属性, 我们无中生有,这就是js的好处
            cc.clicked=1;
        cc.clicked++;  //为了每次让state重新渲染,走render,我每次都+1,让它变化
    
        if(!cc.animation)  //model里animation属性也没有,我们凭空捏造一个,控制动画效果
            cc.animation='rubberBand';
    
        if(cc.FIsLiked){ //这个属性model是有的
            cc.FNLike -= 1;
            cc.FIsLiked = false;
            cc.animation = 'swing';
        }else{
            cc.FNLike += 1;
            cc.FIsLiked = true;
            cc.animation = 'rubberBand';
        }
    
        this.setState({
            dbcomm : baseDataSource.cloneWithRows(dbComments), //改变state,让它重新render
        });
    
    }