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(步调)

相关推荐

  1. 进度 横向/竖向

    2024-02-05 09:56:04       34 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-05 09:56:04       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-05 09:56:04       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-05 09:56:04       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-05 09:56:04       18 阅读

热门阅读

  1. 自然语言处理中所有任务的概括

    2024-02-05 09:56:04       27 阅读
  2. 十大设计模式总结版

    2024-02-05 09:56:04       24 阅读
  3. 算法题目题单——图论

    2024-02-05 09:56:04       30 阅读
  4. C#、Unity:Time 时间与计时

    2024-02-05 09:56:04       20 阅读
  5. 软件架构风格:您的系统设计指南

    2024-02-05 09:56:04       30 阅读
  6. 简单介绍Spring Security 的认证机制和授权机制

    2024-02-05 09:56:04       30 阅读
  7. k8s版本升级到1.24.x

    2024-02-05 09:56:04       34 阅读