当前位置: 首页 > article >正文

ReactNative实现的横向滑动条

OK,我们先看下效果图

注意使用到了两个库

1.react-native-linear-gradient

2.react-native-gesture-handler

ok,我们看下面的代码

import {Image, TouchableWithoutFeedback, StyleSheet, View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import React from 'react';
import {
  Gesture,
  GestureDetector,
  GestureHandlerRootView,
} from 'react-native-gesture-handler';
export class HorizntalSlider extends React.Component {
  shouldComponentUpdate(
    nextProps: Readonly<P>,
    nextState: Readonly<S>,
    nextContext: any,
  ): boolean {
    return false;
  }
  constructor(props) {
    super(props);
    this.progress = props.initValue;
    this.step = props.step;
    this.range = props.max - props.min;
    this.currentX = 0;
    this.enable = true;
  }
  _setValueChange(value) {
    this.currentX = value;
    this.selectedTrack.setNativeProps({
      style: {width: value},
    });
    let indicatorValue = value - 5 > 0 ? value - 5 : 0;
    this.indicator.setNativeProps({
      style: {left: indicatorValue - 1},
    });
  }

  componentDidMount(): void {
    if (this.props) {
      this.setPowerState(this.props.openState);
    }
  }

  _add() {
    if (!this.enable) {
      showToast(this.tips);
      const {onEnableClick} = this.props;
      if (onEnableClick) {
        onEnableClick();
      }
      return;
    }
    let tempValue = this.progress + this.step;
    this.progress =
      tempValue > this.props.max ? this.props.max : tempValue;
    let styleValue =
      ((this.progress - this.props.min) / this.range) * 250;
    this._setValueChange(styleValue);
    const {onLastChange, onChange} = this.props;
    onChange(this.progress);
    onLastChange(this.progress);
  }

  _reduce() {
    if (!this.enable) {
      const {onEnableClick} = this.props;
      if (onEnableClick) {
        onEnableClick();
      }
      showToast(this.tips);
      return;
    }
    let tempValue = this.progress - this.step;
    this.progress =
      tempValue < this.props.min ? this.props.min : tempValue;
    let styleValue =
      ((this.progress - this.props.min) / this.range) * 250;
    this._setValueChange(styleValue);
    const {onLastChange, onChange} = this.props;
    onChange(this.progress);
    onLastChange(this.progress);
  }

  _onValueChange(x, isFinalize = false) {
    if (x > 250) {
      x = 250;
    }
    if (x < 0) {
      x = 0;
    }
    this.currentX = x;
    this.progress = this.props.min + parseInt((x / 250) * this.range);
    // if (isFinalize) {
    //   const {onLastChange} = this.props;
    //   onLastChange(this.progress);
    // } else {
    //   const {onChange} = this.props;
    //   onChange(this.progress);
    // }
    this._setValueChange(x);
  }

  setPowerState(state) {
    if (!this.props) {
      return;
    }
    if (state === 1) {
      this.selectedTrack.setNativeProps({
        style: {
          width: this.currentX,
        },
      });
      this.indicator.setNativeProps({
        style: {opacity: 1},
      });
    } else {
      this.selectedTrack.setNativeProps({
        style: {width: 0},
      });
      this.indicator.setNativeProps({
        style: {opacity: 0},
      });
    }
  }

  setEnable(isEnable, tips) {
    if (!this.props) {
      return;
    }
    this.enable = isEnable;
    this.tips = tips;
  }

  gesture = Gesture.Pan()
    .onBegin(e => {
      this._onValueChange(e.x);
    })
    .onUpdate(e => {
      this._onValueChange(e.x);
    })
    .onFinalize(e => {
      this._onValueChange(e.x, true);
    });

  render() {
    this.currentX = ((this.progress - this.props.min) / this.range) * 250;
    this.currentX = this.currentX > 0 ? this.currentX : 0;
    return (
      <View style={[styles.mainContainer, this.props.style]}>
        <GestureHandlerRootView>
          <GestureDetector gesture={this.gesture}>
            <View style={styles.sliderContainer}>
              <LinearGradient
                start={{x: 0, y: 0}}
                end={{x: 1, y: 0}}
                colors={['#4372FF', 'white', '#FF4D4F']}
                style={{
                  width: 252,
                  height: 60,
                }}
              />
              <View
                style={{
                  flexDirection: 'row',
                  alignItems: 'center',
                  position: 'absolute',
                }}>
                <View
                  ref={c => (this.selectedTrack = c)}
                  style={{
                    width: this.currentX,
                    opacity: 0,
                    height: 60,
                  }}
                />
                <View
                  style={{
                    flex: 1,
                    backgroundColor: '#12161a',
                    opacity: 0.8,
                    height: 60,
                  }}
                />
              </View>
              <View
                ref={c => (this.indicator = c)}
                style={[styles.indicator, {left: this.currentX - 7}]}
              />
            </View>
          </GestureDetector>
        </GestureHandlerRootView>
      </View>
    );
  }
}

class Track extends React.Component {
  constructor(props) {
    super(props);
    this.unitViewArr = [];
    for (let i = 0; i < 42; i++) {
      this.unitViewArr[i] = i;
    }
  }
  shouldComponentUpdate(
    nextProps: Readonly<P>,
    nextState: Readonly<S>,
    nextContext: any,
  ): boolean {
    return false;
  }

  render() {
    return (
      <View style={styles.trackContainer}>
        {this.unitViewArr.map((item, index) => {
          return (
            <View
              key={index}
              style={{flexDirection: 'row', alignItems: 'center'}}>
              <View
                style={{
                  height: 60,
                  width: 2,
                  opacity: 0,
                  backgroundColor: '#12161a',
                  borderRadius: 100,
                }}
              />
              <View
                style={{height: 60, width: 4, backgroundColor: '#12161a'}}
              />
            </View>
          );
        })}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  mainContainer: {
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
  },
  sliderContainer: {
    position: 'relative',
    justifyContent: 'center',
    paddingVertical: 10,
    marginLeft: 10,
    marginRight: 8,
  },
  trackContainer: {
    width: 252,
    flexDirection: 'row',
    position: 'absolute',
  },
  actionImg: {
    width: 60,
    height: 60,
  },
  thumb: {
    height: 34,
    width: 7,
    backgroundColor: 'transparent',
  },
  indicator: {
    width: 0,
    height: 0,
    position: 'absolute',
    top: -2,
    borderLeftWidth: 4,
    borderTopWidth: 4,
    borderRightWidth: 4,
    left: -3,
    borderTopColor: '#FF6A6B',
    borderLeftColor: 'transparent',
    borderRightColor: 'transparent',
  },
});
export default HorizntalSlider;

使用代码如下

        <GestureHandlerHorizntalSlider
              model={{
                initValue: 20,
                step: 10,
                max: 100,
                min: 0,
              }}>
       </GestureHandlerHorizntalSlider>

拖动条:max(最大值),min(最小值),initValue(当前值),step(步调)


http://www.kler.cn/a/228750.html

相关文章:

  • Golang Gin系列-1:Gin 框架总体概述
  • 通过idea创建的springmvc工程需要的配置
  • Excel中函数SIGN()的用法
  • macOS Sequoia 15.3 beta3(24D5055b)发布,附黑、白苹果镜像下载地址
  • flutter开发-figma交互设计图可以转换为flutter源代码-如何将设计图转换为flutter源代码-优雅草央千澈
  • 机器学习:监督学习与非监督学习
  • K8S之Namespace的介绍和使用
  • ubuntu离线安装k8s
  • Python中的while循环,知其然知其所以然
  • ###C语言程序设计-----C语言学习(9)#函数基础
  • 【实战系列----消息队列 数据缓存】rabbitmq 消息队列 搭建和应用
  • C语言第十八弹---指针(二)
  • windows10忘记密码的解决方案
  • 前端JavaScript篇之JavaScript为什么要进行变量提升,它导致了什么问题?什么是尾调用,使用尾调用有什么好处?
  • protoc结合go完成protocol buffers协议的序列化与反序列化
  • BFS——双向广搜+A—star
  • 阿里云计算巢是什么?计算巢服务详细介绍
  • 无锁序列系列笔记
  • 使用MySQL Workbench连接MySQL很慢
  • vue2.0+使用md-edit编辑器
  • Android学习之路(29) Gradle初探
  • Django学习记录02
  • Camera2+OpenGL ES+MediaCodec+AudioRecord实现录制音视频写入H264 SEI数据
  • 大数据信用报告查询费用一般要多少钱?
  • 设置 相关
  • 共享网盘系统PHP源码