UNPKG

react-native-draggablelist

Version:
188 lines (164 loc) 7.07 kB
'use strict'; import React , {Component, PropTypes} from 'react' import { Animated, LayoutAnimation, PanResponder, StyleSheet, View, } from 'react-native'; var TimerMixin = require('react-timer-mixin'); var AnimateCell = React.createClass({ mixins: [TimerMixin], getInitialState: function () { return { pan: new Animated.ValueXY(), // 减少样本矢量. pop: new Animated.Value(0), // 初值. shouldUpdate: false, }; }, shouldComponentUpdate(nextProps, nextState) { if(nextProps.shouldUpdate || (nextState.shouldUpdate !== this.state.shouldUpdate)) { return true; } return false; }, _onLongPress(): void { this.props.toggleScroll(false, this.toSetPanResponder); }, toSetPanResponder() { var config = {tension: 40, friction: 3}; this.state.pan.addListener((value) => { //监听value的改变 this.props.onMove && this.props.onMove(value); }); Animated.spring(this.state.pop, { toValue: 1, // pop到这个值,即节点变大 ...config, }).start(); this.setState({panResponder: PanResponder.create({ onStartShouldSetPanResponder: () => true, onPanResponderMove: Animated.event([ null, // native event - ignore {dx: new Animated.Value(0), dy: this.state.pan.y}, // links pan 这里设置关联的pan偏移量 ]), onPanResponderTerminate: (evt, gestureState) => { // console.log('onPanResponderTerminate'); this.props.toggleScroll(true); LayoutAnimation.easeInEaseOut(); // animates layout update as one batch Animated.spring(this.state.pop, { toValue: 0, // Pop back to 0 ...config, }).start(); this.setState({panResponder: undefined}); this.props.onMove && this.props.onMove({ x: gestureState.dx + this.props.restLayout.x, y: gestureState.dy + this.props.restLayout.y, }); this.props.onActivate && this.props.onActivate(); this.props.onDeactivate && this.props.onDeactivate(); this.setState({shouldUpdate: false}); }, onPanResponderRelease: (e, gestureState) => { // console.log('onPanResponderRelease'); LayoutAnimation.easeInEaseOut(); // animates layout update as one batch Animated.spring(this.state.pop, { toValue: 0, // Pop back to 0 ...config, }).start(); this.setState({panResponder: undefined}); this.props.onMove && this.props.onMove({ x: gestureState.dx + this.props.restLayout.x, y: gestureState.dy + this.props.restLayout.y, }); this.props.onDeactivate(); this.setState({shouldUpdate: false}); this.props.toggleScroll(true); }, })}, () => { this.setState({shouldUpdate: true}); // console.log('onActivate'); this.props.onActivate(); }); }, render(): ReactElement { var dragStyle = { position: 'relative', transform:[{'translate':[0,0,0]}], } if (this.state.panResponder) { var handlers = this.state.panResponder.panHandlers; var tmpLayout = this.state.pan.getLayout(); dragStyle = { // Used to position while dragging position: 'absolute', // Hoist out of layout left: 0, right: 0, transform:[{'translate':[0,0,1]}], ...tmpLayout, // Convenience converter }; } else { var oriPageXY = {pageX: 0, pageY: 0}; handlers = { onStartShouldSetResponder: () => true, onResponderGrant: (evt, gestureState) => { this.state.pan.setValue({x: 0, y: 0}); // reset this.state.pan.setOffset(this.props.restLayout); // offset from onLayout this.longTimer = this.setTimeout(this._onLongPress, 300); var evt_native = evt.nativeEvent; oriPageXY = {pageX: evt_native.pageX, pageY: evt_native.pageY }; }, onResponderMove: (evt, gestureState) => { // console.log('onResponderMove'); var evt_native = evt.nativeEvent; this.setState({shouldUpdate: false}); this.clearTimeout(this.longTimer); }, onResponderRelease: () => { // console.log('onResponderRelease'); if (!this.state.panResponder) { this.setState({shouldUpdate: false, panResponder: undefined}); this.clearTimeout(this.longTimer); //this.props.onDeactivate && this.props.onDeactivate(); this.props.toggleScroll(true); this.props.onPressCell && this.props.onPressCell(this.props.rowData); // console.log('onResponderRelease _toggleIsActive'); }else{ this.setState({shouldUpdate: false}); } } }; } var animatedStyle: Object = { shadowOpacity: this.state.pop, // no need for interpolation transform: [ {scale: this.state.pop.interpolate({ inputRange: [0, 1], outputRange: [1, 1] // scale up from 1 to 1.3 })} ], }; var openVal = this.props.openVal; if (this.props.dummy) { animatedStyle.opacity = 0; } var CellComponent = this.props.cellComponent; var shouldUpdate = this.state.shouldUpdate || (this.props.shouldUpdateId == this.props.rowData.id); var props = {dragHandlers: handlers, shouldUpdate: shouldUpdate, rowData: this.props.rowData}; var content = (<CellComponent {...this.props.cellProps} {...props}/>); return ( <Animated.View onLayout={this.props.onLayout} style={[styles.dragView, animatedStyle, dragStyle]}> {content} </Animated.View> ); }, }); var styles = StyleSheet.create({ dragView: { shadowRadius: 10, shadowColor: 'rgba(0,0,0,0.7)', shadowOffset: {height: 8}, backgroundColor: 'transparent', }, }); module.exports = AnimateCell;