在React Native中如何在ScrollView中使用动画视图?

时间:2018-12-06 21:01:13

标签: javascript reactjs react-native

对于我的单位列表中的每个视图,它都具有滑动功能,因此,如果用户向左滑动,则可以选择删除该购物车。当我有较长的购物车列表时,尽管它们不垂直滚动。就像触摸碰到了各个购物车视图的滑动逻辑一样。如何在保留ScrollView功能的同时还保留其中各个视图的各个动画轻扫功能?

父级:CartSummary组件包含“购物车视图”

<ScrollView>
    <FlatList 
        data={availableCarts}
        keyExtractor={(item, index) => (item && item.customer) ? item.customer.customerId : index.toString()}
        renderItem={({item}) => <CartSummary cart={item} onSelect={this.selectCart} />}
/>
</ScrollView>

这是CartSummary组件:

CartSummary类扩展了组件{     cartXPos = new Animated.Value(0);

constructor(props) {
    super(props);

    this.state = {
        verticalPos: 0
    }
}

deleteCart = () => {
    this.props.dispatch(emptyCart(this.props.cart.customer.customerId));
}

viewPanResponder = PanResponder.create({
    onStartShouldSetPanResponder: () => true,
    onPanResponderMove: (e, gs) => {
        // Only set the value if the user swipes left.
        if (Math.sign(gs.dx) === -1) {
            this.cartXPos.setValue(gs.dx);
        }
    },
    onPanResponderRelease: (e, gs) => {
        this.width = Dimensions.get('window').width;
        const touchStart = e.touchHistory.touchBank[0].startTimeStamp;
        const touchFinish = e.touchHistory.touchBank[0].currentTimeStamp;
        const result = touchFinish - touchStart;
        const resultBool = result < 150;
        const noVertical = gs.vy < 0.05;
        this.setState({verticalPos: gs.vy});

        // If the user swipes completely accross the screen to the left then just delete the cart.
        if ((Math.sign(gs.dx) === -1) && (Math.abs(gs.dx) > this.width * 0.8) && noVertical) {
            this.deleteCart();

            Animated.timing(this.cartXPos, {
                toValue: this.width,
                duration: 50
            }).start();
        } 
        // If the user swipes more than 25% of the screen's width to the left show a delete box option.
        else if ((Math.sign(gs.dx) === -1) && (Math.abs(gs.dx) > this.width * 0.25) && noVertical) {
            const position = this.width * 0.20;

            Animated.timing(this.cartXPos, {
                toValue: -position,
                duration: 150
            }).start();
        } 
        // Small touches will act as a normal press touch and take the user to the next screen.
        else if ((Math.abs(gs.dx) < this.width * 0.01) && (touchFinish - touchStart < 100) && noVertical) {
            this.props.onSelect(this.props.cart.customer.customerId);

            Animated.timing(this.cartXPos, {
                toValue: 0,
                duration: 150
            }).start();
        }
        // Reset the cart view position.
        else {
            Animated.timing(this.cartXPos, {
                toValue: 0,
                duration: 0
            }).start();
        }
    }
});

render() {
    const {cart} = this.props;
    const {customer} = cart;

    return (
        <View style={styles.wrapper}>
            <Animated.View {...this.viewPanResponder.panHandlers} style={[styles.animatedView, {left: this.cartXPos}]}>
            <View>
                <Text>Vertical Position: {this.state.verticalPos}</Text>
            </View>     
                <View style={styles.cart}>
                    <View>
                        <View style={styles.lineItem}>
                            <Text style={styles.lineText}>{customer.customerName + ' #' + customer.customerId.trim()}</Text>    
                        </View>

                        <View style={styles.lineItem}>
                            <Text style={styles.lineText}>Cases: {cart.cases}</Text>    
                        </View>

                        <View style={styles.lineItem}>
                            <Text style={styles.lineText}>Updated: {cart.lastModified}</Text>    
                        </View>    
                    </View>
                    <MBIcon name='ico-24-chevron-right' style={styles.lineText} />
                </View>
            </Animated.View>
            <TouchableOpacity style={styles.deleteBox} onPress={() => this.deleteCart()}>
                <MBIcon name="ico-24-trash" size={30}  style={styles.searchIcon} />
                <Text style={styles.lineText}>( {cart.cases} )</Text>    
            </TouchableOpacity>      
        </View>
    );
}

}

0 个答案:

没有答案