ReactNative實現(xiàn)的橫向滑動條效果
ReactNative實現(xiàn)的橫向滑動條
推薦文章
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(當(dāng)前值),step(步調(diào))
補充:
ReactNative基于寬度變化實現(xiàn)的動畫效果


效果如上圖所示,通過修改設(shè)備寬度實現(xiàn)動畫效果
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, // 讓動畫持續(xù)一段時間
// Style property 'width' is not supported by native animated module
useNativeDriver: false,
},
).start(); // 開始執(zhí)行動畫
}, [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:注意上面的代碼和截圖不一致;但是代碼是可以實現(xiàn)上面的效果的。
到此這篇關(guān)于ReactNative實現(xiàn)的橫向滑動條的文章就介紹到這了,更多相關(guān)ReactNative橫向滑動條內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
react使用antd的上傳組件實現(xiàn)文件表單一起提交功能(完整代碼)
最近在做一個后臺管理項目,涉及到react相關(guān)知識,項目需求需要在表單中帶附件提交,怎么實現(xiàn)這個功能呢?下面小編給大家?guī)砹藃eact使用antd的上傳組件實現(xiàn)文件表單一起提交功能,一起看看吧2021-06-06
React?Native系列之Recyclerlistview使用詳解
這篇文章主要為大家介紹了React?Native系列之Recyclerlistview使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
關(guān)于React狀態(tài)管理的三個規(guī)則總結(jié)
隨著 JavaScript 單頁應(yīng)用開發(fā)日趨復(fù)雜,JavaScript 需要管理比任何時候都要多的 state (狀態(tài)),這篇文章主要給大家介紹了關(guān)于React狀態(tài)管理的三個規(guī)則,需要的朋友可以參考下2021-07-07
react setupProxy.js導(dǎo)致項目無法啟動的解決
這篇文章主要介紹了react setupProxy.js導(dǎo)致項目無法啟動的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
react?app?rewrited替代品craco使用示例
這篇文章主要為大家介紹了react?app?rewrited替代品craco使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11

