React Native实现应用中心图标拖动功能

react

      React Native (简称RN)是Facebook于2015年4月开源的跨平台移动应用开发框架,是Facebook早先开源的UI框架 React 在原生移动应用平台的衍生产物,目前支持iOS和安卓两大平台。RN使用Javascript语言,类似于HTML的JSX,以及CSS来开发移动应用,因此熟悉Web前端开发的技术人员只需很少的学习就可以进入移动应用开发领域。(百度百科)

      小编有幸参与了公司APP的开发,该APP采用混合式开发,本人负责RN的几个功能的开发,其中最复杂的就是应用中心的功能,如下图所示。模块分为上下两部分,下面是所有应用,上面是下方勾选的应用,可以上下左右滑动(图中只有一行,后面改成了两行,故可以上下或者斜着滑动,偷懒就不截图了)

         所以一共要实现接收数据、选择应用、调整顺序、提交这个几个功能,下面重点讲述调整顺序的代码,其他的代码可能会掠过。

1、获取数据

定一个几个变量,用于保存我的应用和所有应用,获取数据调用了原生的方法,大家用RN的获取数据的方法是一样的。

在构造器里面的变量

this.myapps = [];

this.application= [];

//获取数据

dsfectchData(){

RNBridgeManager.queryAppList((error, result) => {

if(error){

console.log("---q--->error:" + error);

}else{

var myapp = [];

for(var i=0;i<result.length;i++){

if(result[i].myAppList == 1){

myapp.push(result[i]);

console.log( i + " : " + result[i].appId);

}

}

this.myapps = myapp; //保存我的应用数据

console.log("this.myapps" + this.myapps.length);

this.application = result; // 保存所有数据

}

});

}

2、展示数据

重点来看我的应用的数据展示方式,如下图第一个红色标记的是将数据放入到一个数组中,这个数据记录

顺序;第二个红色标记用于和上一个标记中的order数组一起,用于排序和重新展示;第三个红色标记的

部分是每个可拖动的图标的定位,当然首先要将定位设定为:position = 'absolute'。绿色底标注

的为可拖动的核心,即触摸操作。

<View style={{flexDirection: 'row',height:25,backgroundColor: '#fff',alignItems: 'center',paddingTop:10,marginTop:px2pt(10)}}>

    <Image

source={{uri:this.state.navbar}}

style={{width:3,height:15,marginLeft:px2pt(10)}}

/>

<Text style={styles.itemTitle}>我的应用</Text>

<Text style={styles.itemTitleDes}>(按住拖动调整顺序)</Text>

</View>

<View style={styles.containerMy}>

{this.myapps.map((item, i)=>{

this.order.push(item);

return (

<View

{...this._panResponder.panHandlers}

ref={(ref) => this.items[i] = ref}

key={i}

style={[styles.item, {top: (parseInt(i/4))*90 + 10,left:(i%4)*this.widthSreen}]}>

<Image

source={{uri:this.state.shortcut_icon_bg}}

style={styles.thumbnail}

/>

<Image

source={this._getApplicationIcons(item.appId)}

style={styles.thumbnailInside}

/>

<TextActivity text={item.appName} width={containerWidth}/>

<TouchableWithoutFeedback onPress={this._pressIcon.bind(this,this.myapps,i,1)} style={styles.buttonRightTop}>

<Image

source={{uri:this.state.shortcut_icon_del}}

style={styles.imageRightTop}

/>

</TouchableWithoutFeedback>

</View>

);

})}

</View>

3、滑动操作部分,此部分依次为

1)点击时判定是哪个图标(根据坐标)

2)判定移动位置是否已经和其他的图标有重合,如果有,则交换两个图标的位置

3)释放后的显示结果

componentWillMount(){

this._panResponder = PanResponder.create({

onStartShouldSetPanResponder: (evt, gestureState) => true,

onMoveShouldSetPanResponder: (evt, gestureState) => true,

onPanResponderGrant: (evt, gestureState) => {

const {pageX,pageY, locationX,locationY} = evt.nativeEvent;

console.log("--eric-->:pageX:" + pageX + "--pageY:" + pageY + "--locationX:" + locationX + "--locationY:" + locationY);

this.index = this._getIdByPosition(pageX,pageY);

//逻辑应该是点击的一瞬间,判定是第几个 (parseInt(i/4))*90,left:(i%4)*this.widthSreen}

this.preX = (this.index%4)*this.widthSreen;

this.preY = (parseInt(this.index/4))*90 + 10;

//get the taped item and highlight it

let item = this.items[this.index];

if(item!=null){

item.setNativeProps({

style: {

shadowColor: "#000",

shadowOpacity: 0.3,

shadowRadius: 5,

shadowOffset: {height: 0, width: 2},

elevation: 5

}

});

}

},

        // 移动判定是否进入了某个图标的领域,如果进入则交换

         onPanResponderMove: (evt, gestureState) => {

let left = this.preX + gestureState.dx;

let top = this.preY + gestureState.dy;

console.log("--eric-->top:" + top + ":" + gestureState.dy);

let item = this.items[this.index];

if(item!=null) {

item.setNativeProps({

style: {left: left,top: top}

});

}

let collideIndex = this._getIdByPosition(evt.nativeEvent.pageX,evt.nativeEvent.pageY);

if(collideIndex !== this.index && collideIndex !== -1) {

let collideItem = this.items[collideIndex];

if(collideItem!=null){

collideItem.setNativeProps({

style: {left: this._getLeftValueYById(this.index),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

};

let item = this.items[this.index];

//go back the correct position

if(item!=null){

item.setNativeProps({

style: {...shadowStyle, left: this._getLeftValueYById(this.index),top: this._getTopValueYById(this.index)}

});

}

console.log(this.order);

},

onPanResponderTerminate: (evt, gestureState) => {

// Another component has become the responder, so this gesture

// should be cancelled

}

});

}


以上是 React Native实现应用中心图标拖动功能 的全部内容, 来源链接: utcz.com/z/381512.html

回到顶部