React-Native RN list drag and drop item exchange function

React-Native RN list drag and drop item exchange function

To develop the Mijia project using the RN framework, you need to write a method to edit the component page that can be dragged and deleted, and record it;

insert image description here

You can press and hold the icon on the right to drag, and the delete icon on the left to delete the current item

//这里可根据需要引用
import React from 'react';
import {
    
     Image, View, Text,StyleSheet,TouchableOpacity,PanResponder } from 'react-native';
import NavigationBar from 'miot/ui/NavigationBar';
import common from "../../resources/css/common";
import {
    
     AbstractDialog,LoadingDialog } from "miot/ui/Dialog";
import {
    
     RkButton,RkText } from "react-native-ui-kitten";
import PluginStrings from "../../resources/strings";

 export default class MassageTechniqueEditor extends React.Component {
    
    
  /**
   * 页面内部自定义Header
   * @param navigation
   * @returns {
    
    {header: *}|{header: null}}
   */
  static navigationOptions = ({
    
     navigation }) => {
    
    
    const {
    
     titleProps } = navigation.state.params || {
    
    };
    if (!titleProps) return {
    
     header: null };
    return {
    
    
      header: <NavigationBar {
    
    ...titleProps} />
    };
  };
  constructor(props) {
    
    
    super(props);
    this.initNavigationBar()
    this.state={
    
    
      names:[{
    
    
        method:'肩部',
        effots:'50',//力度
        info:'指压'
      },{
    
    
        method:'颈部',
        effots:'30',//力度
        info:'指压'
      },{
    
    
        method:'手部',
        effots:'40',//力度
        info:'指压'
      },{
    
    
        method:'脚部',
        effots:'60',//力度
        info:'指压'
      },{
    
    
        method:'肩部',
        effots:'50',//力度
        info:'指压'
      },{
    
    
        method:'颈部',
        effots:'30',//力度
        info:'指压'
      },{
    
    
        method:'手部',
        effots:'40',//力度
        info:'指压'
      },{
    
    
        method:'脚部',
        effots:'60',//力度
        info:'指压'
      }]
    }
    this.items = [];
    this.order = [];
  }
  initNavigationBar() {
    
    
    this.props.navigation.setParams({
    
    
      titleProps: {
    
    
        left: [
          {
    
    
            key: NavigationBar.ICON.CLOSE,
            onPress: () => {
    
    
              this.setState({
    
    
                visible: true,
              });
            },
          },
        ],
        right: [
          {
    
    
            key: NavigationBar.ICON.COMPLETE,
            onPress: () => {
    
    
              this.setState({
    
    
                loadingVisiable:true
              })
            },
          },
        ],
      }
    });
  }

  render(){
    
    
      return(
          <View style={
    
    styles.container}>
            <Text style={
    
    common.navTit}>手法编辑</Text>
              {
    
    this.state.names.map((item, i)=>{
    
    
                this.order.push(item);
                return (
                  <View
                    ref={
    
    (ref) => {
    
    
                      this.items[i] = ref
                    }}
                    key={
    
    i}
                    style={
    
    [styles.item, {
    
    top: (i+1)*72}]}>
                    <View style={
    
    {
    
    flexDirection: 'row',alignItems:'center'}}>
                    <TouchableOpacity
                        style={
    
    {
    
    width:22,height:22}}
                        onPress={
    
    ()=>{
    
    
                          const arrs= this.state.names;
                          arrs.splice(i,1);
                          this.setState({
    
    
                            names:arrs
                          });
                        }}
                    >
                      <Image
                        style={
    
    {
    
    width:22,height:22}}
                        source={
    
    require("../../resources/images/delete1.png")}
                      />
                  </TouchableOpacity>

                      <Image
                        style={
    
    styles.imgbody}
                        source={
    
    require("../../resources/images/icon/rubItOn.png")}
                      />
                      <View style={
    
    {
    
    marginLeft:12}}>
                        <Text style={
    
    {
    
    fontSize:16,color:'#000'}}>{
    
    item.method}</Text>
                        <Text style={
    
    {
    
    fontSize:13,color:'rgba(0,0,0,0.6)'}}>{
    
    item.info} | 力度{
    
    item.effots}</Text>
                      </View>
                    </View>
                    <Image
                    {
    
    ...this._panResponder.panHandlers}//根据手势拖动方法来实现,可根据需求把此方法放到需要可拖动的地方
                      style={
    
    {
    
    width:22,height:22}}
                      source={
    
    require("../../resources/images/sort.png")}
                    />
                  </View>
                );
              })}
            
          </View>
      );
  }

  componentWillMount(){
    
    
      this._panResponder = PanResponder.create({
    
    
        onStartShouldSetPanResponder: (evt, gestureState) => true,//开启手势响应
        onMoveShouldSetPanResponder: (evt, gestureState) => true,//开启移动手势响应
        onPanResponderGrant: (evt) => {
    
    //手指触碰屏幕那一刻触发
            const {
    
    pageY, locationY} = evt.nativeEvent;
            let num=pageY
            num=num-70
            this.index = this._getIdByPosition(num);
            this.preY = num - locationY;
            //get the taped item and highlight it
            if(this.index==-1){
    
    
              return false
            }
            let item = this.items[this.index];
            item.setNativeProps({
    
    
                style: {
    
    
                  shadowColor: "#000",
                  shadowOpacity: 0.3,
                  shadowRadius: 5,
                  shadowOffset: {
    
    height: 0, width: 2},
                  elevation: 5
                }
            });

        },
        onPanResponderMove: (evt, gestureState) => {
    
    //手指在屏幕上移动触发
            let top = this.preY + gestureState.dy;
            if(this.index==-1){
    
    
              return false
            }
            let item = this.items[this.index];
            item.setNativeProps({
    
    
                style: {
    
    top: top}
            });

            let collideIndex = this._getIdByPosition(evt.nativeEvent.pageY);
            if(collideIndex !== this.index && collideIndex !== -1) {
    
    
                let collideItem = this.items[collideIndex];
                collideItem.setNativeProps({
    
    
                    style: {
    
    top: this._getTopValueYById(this.index)}
                });
                //swap two values
                [this.items[this.index], this.items[collideIndex]] = [this.items[collideIndex], this.items[this.index]];
                [this.order[this.index], this.order[collideIndex]] = [this.order[collideIndex], this.order[this.index]];
                this.index = collideIndex;
            }
        },
        onPanResponderTerminationRequest: (evt, gestureState) => true,//当有其他不同手势出现,响应是否中止当前的手势
        onPanResponderRelease: (evt, gestureState) => {
    
    //手指离开屏幕触发
            const shadowStyle = {
    
    
                shadowColor: "#000",
                shadowOpacity: 0,
                shadowRadius: 0,
                shadowOffset: {
    
    height: 0, width: 0,},
                elevation: 0
            };
            if(this.index==-1){
    
    
              return false
            }
            let item = this.items[this.index];
            //go back the correct position
            item.setNativeProps({
    
    
                style: {
    
    ...shadowStyle, top: this._getTopValueYById(this.index)}
            });
        },
        onPanResponderTerminate: (evt, gestureState) => {
    
    //当前手势中止触发
            // Another component has become the responder, so this gesture
            // should be cancelled
        }
      });
  }

  _getIdByPosition(pageY){
    
    
      var id = -1;
      const height = 72;

      if(pageY >= height && pageY < height*2)
          id = 0;
      else if(pageY >= height*2 && pageY < height*3)
          id = 1;
      else if(pageY >= height*3 && pageY < height*4)
          id = 2;
      else if(pageY >= height*4 && pageY < height*5)
          id = 3;
      else if(pageY >= height*5 && pageY < height*6)
          id = 4;
      else if(pageY >= height*6 && pageY < height*7)
          id = 5;
      else if(pageY >= height*7 && pageY < height*8)
          id = 6;
      else if(pageY >= height*8 && pageY < height*9)
          id = 7;
      else if(pageY >= height*9 && pageY < height*10)
          id = 8;
      else if(pageY >= height*10 && pageY < height*11)
          id = 9;
      else if(pageY >= height*11 && pageY < height*12)
          id = 10;
      else if(pageY >= height*12 && pageY < height*13)
          id = 11;
      else if(pageY >= height*13 && pageY < height*14)
          id = 12;
      else if(pageY >= height*14 && pageY < height*15)
          id = 13;
      else if(pageY >= height*15 && pageY < height*16)
          id = 14;
      return id;
  }

  _getTopValueYById(id){
    
    
      const height = 72;
      return (id + 1) * height;
  }

}

const styles = StyleSheet.create({
    
    
  container: {
    
    
      flex: 1,
      backgroundColor:'#fff',
      paddingHorizontal:12
  },
  item: {
    
    
      paddingHorizontal:20,
      flexDirection: 'row',
      height:72,
      width: '100%',
      alignItems: 'center',
      justifyContent:'space-between',
      backgroundColor: '#fff',
      borderBottomColor: 'rgba(232,232,232,0.42)',
      borderBottomWidth: 1,
      position: 'absolute',
  },
  imgbody: {
    
    
    resizeMode: "contain",
    height: 36,
    width: 36,
    marginLeft: 10,
  },
})

Guess you like

Origin blog.csdn.net/Min_nna/article/details/126596898
Recommended