ReactNative实现的横向滑动条效果
作者:xvzhengyang
本文介绍了ReactNative实现的横向滑动条效果,本文结合示例代码给大家介绍的非常详细,补充介绍了ReactNative基于宽度变化实现的动画效果,感兴趣的朋友跟随小编一起看看吧
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(步调)
补充:
ReactNative基于宽度变化实现的动画效果
效果如上图所示,通过修改设备宽度实现动画效果
import React, {useRef, useEffect, useState} from 'react'; import {Animated, Text, View, Image} from 'react-native'; const FadeInView = props => { const fadeAnim = useRef(new Animated.Value(0)).current; React.useEffect(() => { Animated.timing( fadeAnim, // 动画中的变量值 { toValue: props.currentWidth, // duration: props.durationTime, // 让动画持续一段时间 // Style property 'width' is not supported by native animated module useNativeDriver: false, }, ).start(); // 开始执行动画 }, [props.currentWidth]); return ( <Animated.View // 使用专门的可动画化的View组件 style={{ ...props.style, width: fadeAnim, // 将宽度绑定到动画变量值 }}> </Animated.View> ); }; // 然后你就可以在组件中像使用`View`那样去使用`FadeInView`了 export default props => { return ( <FadeInView durationTime={props.durationTime} currentWidth={props.currentWidth} style={{height: 310, backgroundColor: 'pink'}}></FadeInView> ); };
使用的代码如下
<LayoutAnimatedWidth currentWidth={this.state.currentWidth} durationTime={this.state.durationTime}> </LayoutAnimatedWidth>
PS:注意上面的代码和截图不一致;但是代码是可以实现上面的效果的。
到此这篇关于ReactNative实现的横向滑动条的文章就介绍到这了,更多相关ReactNative横向滑动条内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!