美文网首页React Native开发
使用Animated.View和PanResponder写了个半

使用Animated.View和PanResponder写了个半

作者: 182058734bf0 | 来源:发表于2021-12-10 15:07 被阅读0次

纯tsx复制即用

import {Animated, PanResponder, StyleSheet, View} from "react-native";
import * as React from "react";
import {useRef, useState} from "react";


interface NJSlideViewProps {
    iWidth: number,
    iHeight: number | 15,
    value: number | 0.5,
    progress: (progress: number, scroll: boolean) => void
    color?: Array<string> | ["white", "red"],
}

export function NJSlideView(props: NJSlideViewProps) {
    let color = ["white", "red"]
    let value=0.5
    if (props.color !== undefined) {
        color = props.color
    }
    if (props.value!==undefined){
        value=props.value>1?1:props.value
    }
    const [parentX, setParentX] = useState(0)
    const pan = useRef(new Animated.ValueXY({x: (props.iWidth - props.iHeight) * value+props.iHeight/2, y: 0})).current;
    const panResponder = PanResponder.create({
        onStartShouldSetPanResponder: () => true,
        onMoveShouldSetPanResponderCapture: () => true,
        onPanResponderGrant: (e, g) => {
            // console.log(e.nativeEvent)
            // console.log(e.nativeEvent.pageX-parentX)
            pan.setOffset({
                x: e.nativeEvent.pageX - parentX ,
                y: 0
            })
        },
        onPanResponderMove: (event, g) => {
            //滑动计算 偏移props.iHeight/2个单位
            let dx = parentX + props.iHeight/2 < g.x0 + g.dx
                ? g.x0 + g.dx < parentX + props.iWidth-props.iHeight/2
                    ? g.dx
                    : parentX + props.iWidth- props.iHeight/2 - g.x0
                : parentX + props.iHeight/2 - g.x0
                pan.setValue({
                    x: dx,
                    y: 0
                })
        },
        onPanResponderRelease: (event,g) => {
            pan.flattenOffset()
        },
    });

    return (
        <View
            onLayout={event => {
                console.log(event.nativeEvent)
                setParentX(event.nativeEvent.layout.x)
            }}
            style={[NJSlideViewStyle.container, {width: props.iWidth,height:props.iHeight}]}>
            <View
                onTouchStart={e => {
                    let progress = e.nativeEvent.locationX / props.iWidth
                    pan.setValue({
                        x: (props.iWidth - props.iHeight) * progress+props.iHeight/2,
                        y: 0
                    })
                    pan.flattenOffset()
                    props.progress(progress, false)
                }}
                style={{width: props.iWidth, height: props.iHeight, position: "absolute", justifyContent: "center"}}>
                <View style={{
                    width: props.iWidth,
                    height: props.iHeight / 3,
                    borderRadius: props.iHeight / 3,
                    backgroundColor: color[0]
                }}>
                    <Animated.View style={{
                        width: pan.x,
                        height: props.iHeight / 3,
                        borderRadius: props.iHeight / 3,
                        backgroundColor: color[1]
                    }}/>
                </View>
            </View>
            <Animated.View
                {...panResponder.panHandlers}
                style={
                    [NJSlideViewStyle.seekbar,
                        {
                            height: props.iHeight,
                            width: props.iHeight,
                            marginLeft: -props.iHeight/2,
                            borderRadius:props.iHeight,
                            backgroundColor: color[1]
                        },
                        pan.getLayout()]}>
            </Animated.View>
        </View>
    )
}

const NJSlideViewStyle = StyleSheet.create({
    container: {
        height: 30,
        alignItems: "flex-start",
        justifyContent: "center",
    },
    seekbar: {
        width: 30,
        height: 30,
        borderRadius: 20,
    }
})


使用方法

                <NJSlideView
                  value={0.01}
                    iWidth={width-80}
                    iHeight={30}
                    color={["white","red"]}
                    progress={(progress, scroll) => {
                        console.log(progress)
                    }}/>
                <NJSlideView
                    value={0.99}
                    iWidth={width-80}
                    iHeight={10}
                    color={["white","#0cee12"]}
                    progress={(progress, scroll) => {
                        console.log(progress)
                    }}/>

效果

Simulator Screen Shot - iPhone 13 - 2021-12-10 at 14.51.11.png

目前的bug是当组件被一个没有具体宽带的View 包裹时,拖拽进度条按钮的偏移量会计算出错。受前面bug的影响拖拽实时的进度我没计算,拖拽完成的进度我也没计算。

我刚开始的写的这个组件是希望能实现年龄段的选择,(就是能在一条线上,选出最大年龄,和最小年龄的功能)。不知道把头发干秃能不能做出来。

相关文章

  • 使用Animated.View和PanResponder写了个半

    纯tsx复制即用 使用方法 效果 目前的bug是当组件被一个没有具体宽带的View 包裹时,拖拽进度条按钮的偏移量...

  • 2021-11-09 React-Native PanRe

    最近想封装一个滑动组件给项目其他组件使用,React Native官方文档中就PanResponder的使用有做大...

  • PanResponder的使用总结

    简介 对于简单的 touch 事件,React Native有4个专门的 touch 组件进行处理 Touchab...

  • RN通过PanResponder 实现单元格拖拽

    什么是PanResponder PanResponder 是 React Native 实现的一套手势相应方法。P...

  • ReactNative手势上滑隐藏下滑显示

    一、实现效果 二、实现方式 1 使用RN的panResponder组件来实现手势滑动### 2 在construc...

  • ReactNative 手势

    View可用的手势 PanResponder 手势监视器 事件参数 每个事件都有两个返回参数nativeEvent...

  • React Native - PanResponder - 捕获

    最近的react-native项目中需要在嵌套元素之间切换获得手势的响应权,那么作为前端的我,第一反应就是 捕获-...

  • RN打造自己的大图查看浏览

    rn触摸手势学习——PanResponder。打造一个大图浏览功能,实现:单击事件、双击事件(双击缩放图片)、长按...

  • 写了一半

    周六,继续加班。 明显感觉到起床的班主任少了。我起来了,嘚瑟一下。 食堂吃早餐的时候,以前能坐满六七张餐桌,今早就...

  • RN手势

    React Native框架底层的手势响应系统提供了响应处理器,PanResponder API将这些手势响应处理...

网友评论

    本文标题:使用Animated.View和PanResponder写了个半

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