使用react native具有可拖动组件的毛刺-使用Animated和PanResponder

时间:2018-10-01 10:02:37

标签: react-native

this问题中汲取灵感,我实现了两个可拖动组件作为视图中的子组件。父视图如下:

import React, { Component } from "react";
import { Text, View, StyleSheet, Dimensions } from "react-native";
import Draggable from "./Draggable";

export default class FloorPlan extends Component {
  constructor() {
    super();
    const { width, height } = Dimensions.get("window");
    this.separatorPosition = (height * 2) / 3;
  }

  render() {
    return (
      <View style={styles.mainContainer}>
        <View style={[...styles.dropZone, { height: this.separatorPosition }]}>
          <Text style={styles.text}>Floor plan</Text>
        </View>
        <View style={styles.drawerSeparator} />
        <View style={styles.row}>
          <Draggable />
          <Draggable />
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  mainContainer: {
    flex: 1
  },
  drawerSeparator: {
    backgroundColor: "grey",
    height: 20
  },
  row: {
    flexDirection: "row",
    marginTop: 25
  },
  dropZone: {
    height: 700,
    backgroundColor: "#f4fffe"
  },
  text: {
    marginTop: 25,
    marginLeft: 5,
    marginRight: 5,
    textAlign: "center",
    color: "grey",
    fontSize: 20
  }
});

可拖动组件的实现如下:

import React, { Component } from "react";
import {
  StyleSheet,
  View,
  PanResponder,
  Animated,
  Text,
  Dimensions
} from "react-native";

export default class Draggable extends Component {
  constructor() {
    super();
    const { width, height } = Dimensions.get("window");
    this.separatorPosition = (height * 2) / 3;
    this.state = {
      pan: new Animated.ValueXY(),
      circleColor: "skyblue"
    };
    this.currentPanValue = { x: 0, y: 0 };
    this.panListener = this.state.pan.addListener(
      value => (this.currentPanValue = value)
    );
  }

  componentWillMount() {
    this.state.pan.removeListener(this.panListener);
  }

  componentWillMount() {
    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponder: (evt, gestureState) => false,
      onMoveShouldSetPanResponder: (evt, gestureState) => false,
      onMoveShouldSetPanResponderCapture: (evt, gesture) => {
        return true;
      },
      onPanResponderGrant: (e, gestureState) => {
        this.setState({ circleColor: "red" });
      },
      onPanResponderMove: (event, gesture) => {
        Animated.event([
          null,
          {
            dx: this.state.pan.x,
            dy: this.state.pan.y
          }
        ])(event, gesture); 
      },
      onPanResponderRelease: (event, gesture) => {
        this.setState({ circleColor: "skyblue" });
        if (gesture.moveY < this.separatorPosition) {
          this.state.pan.setOffset({
            x: this.currentPanValue.x,
            y: this.currentPanValue.y
          });
          this.state.pan.setValue({ x: 0, y: 0 });
          // this.state.pan.flattenOffset();
        } else {
          //Return icon to start position
          this.state.pan.flattenOffset();
          Animated.timing(this.state.pan, {
            toValue: {
              x: 0,
              y: 0
            },
            useNativeDriver: true,
            duration: 200
          }).start();
        }
      }
    });
  }

  render() {
    const panStyle = {
      transform: this.state.pan.getTranslateTransform()
    };
    return (
      <Animated.View
        {...this.panResponder.panHandlers}
        style={[
          panStyle,
          styles.circle,
          { backgroundColor: this.state.circleColor }
        ]}
      />
    );
  }
}

let CIRCLE_RADIUS = 30;
let styles = StyleSheet.create({
  circle: {
    backgroundColor: "skyblue",
    width: CIRCLE_RADIUS * 2,
    height: CIRCLE_RADIUS * 2,
    borderRadius: CIRCLE_RADIUS,
    marginLeft: 25
  }
});

可以将可拖动组件拖动到FloorPlan上,并在下次平移操作时记住其位置。但是,有时在拖动过程中会出现故障,并且图标会在平移的开始处跳转或完全消失。

可能是什么问题?我正在使用React Native 0.55.2进行开发,并使用运行Android 7的设备进行测试。

0 个答案:

没有答案