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