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(當前值),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-06React?Native系列之Recyclerlistview使用詳解
這篇文章主要為大家介紹了React?Native系列之Recyclerlistview使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10關(guān)于React狀態(tài)管理的三個規(guī)則總結(jié)
隨著 JavaScript 單頁應(yīng)用開發(fā)日趨復雜,JavaScript 需要管理比任何時候都要多的 state (狀態(tài)),這篇文章主要給大家介紹了關(guān)于React狀態(tài)管理的三個規(guī)則,需要的朋友可以參考下2021-07-07react setupProxy.js導致項目無法啟動的解決
這篇文章主要介紹了react setupProxy.js導致項目無法啟動的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07react?app?rewrited替代品craco使用示例
這篇文章主要為大家介紹了react?app?rewrited替代品craco使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11