美文网首页
react-native 拖拽走过的路

react-native 拖拽走过的路

作者: 扶搏森 | 来源:发表于2019-11-01 10:46 被阅读0次
this.panResponder = PanResponder.create({
  /***************** 要求成为响应者 *****************/
  // 单机手势是否可以成为响应者
  onStartShouldSetPanResponder: (evt, gestureState) => true,
  // 移动手势是否可以成为响应者
  onMoveShouldSetPanResponder: (evt, gestureState) => true,
  // 拦截子组件的单击手势传递,是否拦截
  onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
  // 拦截子组件的移动手势传递,是否拦截
  onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
  /***************** 响应者事件回调处理 *****************/
  // 单击手势监听回调
  onPanResponderGrant: (e, gestureState) => {
    console.log('onPanResponderGrant==>' + '单击手势申请成功,开始处理手势');
    this._onPanResponderGrant(e);
  },
  // 移动手势监听回调
  onPanResponderMove: throttle((e, gestureState) => {
    console.log('onPanResponderMove==>' + '移动手势申请成功,开始处理手势' + `${gestureState}`);
    this._onPanResponderMove(e, gestureState);
  }, 200),
  // 手势动作结束回调
  onPanResponderEnd: (evt, gestureState) => {
    console.log('onPanResponderEnd==>' + '手势操作完成了,用户离开');
    this._onPanResponderEnd(evt);
  },
  // 手势释放, 响应者释放回调
  onPanResponderRelease: (e, gestureState) => {
    // 用户放开了所有的触摸点,且此时视图已经成为了响应者。
    // 一般来说这意味着一个手势操作已经成功完成。
    this._onPanResponderRelease(e, gestureState);
    console.log('onPanResponderRelease==>' + '放开了触摸,手势结束');
  },
  // 手势申请失败,未成为响应者的回调
  onResponderReject: (e, gestureState) => {
    // 申请失败,其他组件未释放响应者
    console.log('onResponderReject==>' + '响应者申请失败');
    this._onPanResponderRelease(e, gestureState);
  },
  // 当前手势被强制取消的回调
  onPanResponderTerminate: e => {
    // 另一个组件已经成为了新的响应者,所以当前手势将被取消
    console.log('onPanResponderTerminate==>' + '由于某些原因(系统等),所以当前手势将被取消');
    return true;
  },
  onShouldBlockNativeResponder: (evt, gestureState) => {
    return true;
  }
});
  

需求是多个可以拖拽的对象所以需要知道每次是拖拽哪个,而调用方法需要用 {...this.panResponder.panHandlers}解构之后得到的json通过props传递给组件,使得组件变成响应者,打印{...this.panResponder.panHandlers}

绑定事件

多个拖拽就不能知道是哪个变成了响应者

  1. 不用解构,给View绑定事件,传递index

Animated.View绑定事件,如

<Animated.View
  onResponderMove={(nativeEvent, gestureState) => this.onResponderMove(index, nativeEvent, gestureState}
>

将index作为参数传递过去就知道是哪项作为了响应者,但是,参数中gestureState是undefined

[图片上传失败...(image-e75a45-1572576410055)]

官网中说:它提供了一个对触摸响应系统响应器的可预测的包装。对于每一个处理函数,它在原生事件之外提供了一个新的gestureState对象。

所以不用PanResponder.create得不到gestureState对象

2.通过重写解构出来的{...this.panResponder}后的onResponderGrant将index放到state中

List.map(li => (
    <Animated.View
      style={styles.scheduleMoveImgView}
      {...this.panResponder.panHandlers}
      onResponderGrant={e => {
        this.touchY = e.nativeEvent.locationY - 12;
        this.initHeight = ((li.end - li.start) / 1800) * initOneHeight;
        this.dragItem = li;
        this.setState({
          isMove: true,
          movingHeight: this.initHeight,
          dragIndex: index
        });
      }}
    >
    </Animated.View>
))

项目中使用了第二种方法,因为拖拽时需要得到gestureState对象

功能截屏
<ScrollView
  style={{ flex: 1 }}
  scrollEnabled={!isMove}
  ref={view => {
    this.areaScrollView = view;
  }}
>
    <View style={styles.scheduleList}>
        {
            scheduleList.map((li, index) => ())
        }
    </View>
    <View style={styles.lineWrap}>
        {
            scheduleList.map((li, index) => ())
        }
    </View>
    <View style={styles.scheduleSelectList}>
        {
            scheduleSelectList.map((li, index) => ())
        }
    </View>
</ScrollView>

ScrollView的children有3个View,scheduleList是0-24小时的间距,lineWrap是今天线,绝对定位,scheduleSelectList是选中的时间段,绝对定位。

android中的坑

按钮区域
按钮能点击区域

在android里面只有1/4的区域能够点击,ios没事,截图中绿色和黄色的交界处才能点击。原来只有图标能点击(圆圈灰色X,2424),在手机中点击体验不好,改成黄色区域能够点击(5050),因为黄色删除按钮和拖动按钮都是绝对定位,通过拖动,动态设置box(蓝色区域)的height。

box{
    position: 'absolute',
    top,
    height
}

蓝色区域外的区域点击在android中无效

解决方案

<View> // 青色区域,top - 25, 高度 + 50
    <View></View> // 内部边框区域 margin 25
</View>

这个时候,按钮就在区域内了,可以点击按钮全部位置了

接下来就遇到第二个问题

2个box之间间隔一个区域,这个时候就不能选择这个区域了,2个box区域重叠,上面一个box的高度向下25,下面一个box的top向上25,中间的一个区域不能点击

设置区域position: 'absolute', zIndex: 100会导致按钮的3/4能点击,左下角1/4不能点击问题

[图片上传失败...(image-e141fa-1572577317487)]

解决方案

<View> // 一块区域
    <View></View> // 不定位
    <View></View> // 定位(宽度80%)
</View>

解决之后

完美

红色区域在andriod能点击选中

但是在ios中红色区域是在青色的内部(心中感到ios和anroid都有不同的渲染机制,都有坑),只有设置外层的View的zIndex: 100大于青色区域才行,ios中内部View的zIndex是在外层zIndex 的基础上的。所以方案失败。(如果设置外面的View的zIndex: 100,就不能设置width: 80%, 因为每个区域都有一个下边框,80%的话下边框的长度也变成了80%了,可以通过设置内部的View的width为Dimensions.get('window').width*0.8 这时候的下边框就是一样了,最终没采用这种方案)

最终方案

通过设置 scheduleList.map((li, index) => ()) 生成不同时间段的高为0.5的下边框(绝对定位), 内部View展示为80%,效果就是上图一样了

rn的体验等级,能用,凑合,流畅,丝滑

相关文章

  • react-native 拖拽走过的路

    需求是多个可以拖拽的对象所以需要知道每次是拖拽哪个,而调用方法需要用 {...this.panResponder....

  • 初探React-Native

    近日研究了下React-Native,一路走来真是!!!全是眼泪啊!!! 记录下走过的坑,现在把填坑方法送给大...

  • 走过曾走过的路

    不知道从何时起,我们开始走进这个“暗暗”的世界,远处只有一道光,在这个世界里的所有人以及从这个世界走出去的所有...

  • 走过你走过的路

    很久以来想写点属于自己的东西,想时刻提醒自己,不忘初心。 (一)这一年 这一年,太多的...

  • 走过你走过的路

    很久以来想写点属于自己的东西,想时刻提醒自己,留给孩子。 (一)这一年 这一年,太多的不幸与无辜,猝...

  • React-Native ListView拖拽交换Item

    https://blog.csdn.net/w337198302/article/details/53374506

  • React-Native 拖拽列表,滑动删除。

    工作需要,实现了一个可以滑动删除的拖拽列表。 主要是参考的这个网站 https://blog.csdn.net/s...

  • 走过的路

    屋后青竹林 积落陈年叶, 芽枣花开等过整个夏天。 嬉水的孩童, 年少仿佛昨天。 路过白沙古街, 未能多看几眼。 滩...

  • 走过的路

    原创/王小闲的故事 壹 高中...

  • 走过的路

    又是一年的国庆节,已过五天,看着热闹的场景,想起了朱自清荷塘月色里面的话:热闹是他们的,而我,什么也没有。 今天结...

网友评论

      本文标题:react-native 拖拽走过的路

      本文链接:https://www.haomeiwen.com/subject/oukfbctx.html