React Native中实现带圆角虚线边框的圆形进度指示器
React Native SVG 实现带圆角虚线边框的圆形进度指示器
要实现你预期的圆角虚线边框效果,核心是正确使用strokeLineCap属性(而非strokeLinejoin),并合理配置strokeDasharray。以下是具体解决方案:
关键修改点
strokeLineCap='round':这个属性才是控制虚线线段两端圆角的核心,strokeLinejoin仅作用于路径的拐角(圆形路径无拐角,对你的场景无效)。- 明确
strokeDasharray的两个参数:需要同时指定「虚线线段长度」和「线段间距」,比如[12, 8],这样每个虚线段的两端都会显示为圆角。 - 调整参数比例:根据
strokeWidth调整线段长度和间距,避免线段过短导致圆角重叠,影响视觉效果。
修改后的完整代码
import React from 'react'; import { Animated, Easing, Text, StyleSheet, Dimensions, SafeAreaView, TouchableOpacity } from 'react-native'; import Svg, { Circle, Path } from 'react-native-svg'; const { width, height } = Dimensions.get('screen'); const CIRCLE_LENGTH = 1000; const R = CIRCLE_LENGTH / (2 * Math.PI); const AnimatedCircle = Animated.createAnimatedComponent(Circle); export default App = () => { const [playing, setPlaying] = React.useState(true); const percentage = 75; const duration = 76000; const delay = 1000; const max = 100; const animatedValue = React.useRef(new Animated.Value(0)).current; const circleRef = React.useRef(); const animation = (toValue) => { return Animated.timing(animatedValue, { toValue, duration, delay, easing: Easing.bezier(.53, .53, .53, .53), useNativeDriver: true, }).start(() => { animation(toValue === 0 ? percentage : 0); }); }; React.useEffect(() => { animation(percentage); const listenerId = animatedValue.addListener(v => { const maxPerc = (100 * v.value) / max; const strokeDashoffset = CIRCLE_LENGTH - (CIRCLE_LENGTH * maxPerc) / 100; if (circleRef?.current) { circleRef.current.setNativeProps({ strokeDashoffset, }); } }); return () => { animatedValue.removeListener(listenerId); }; }, []); return( <SafeAreaView style={styles.view}> <Svg style={{position: 'absolute'}}> {/* 底层实心圆环 */} <Circle cx={width/2} cy={height/2} r={R} stroke={'#ccc'} strokeWidth={12} /> {/* 动画进度圆环 */} <AnimatedCircle ref={circleRef} cx={width/2} cy={height/2} r={R} stroke={'#3591E7'} strokeWidth={12} strokeLinecap='round' strokeDasharray={CIRCLE_LENGTH} strokeDashoffset={CIRCLE_LENGTH} /> {/* 修改后的圆角虚线圆环 */} <Circle cx={width/2} cy={height/2} r={R-24} stroke={'#ccc'} strokeWidth={25} // 虚线线段长度12,间距8,可根据需求调整 strokeDasharray={[12, 8]} // 关键:开启虚线端点圆角 strokeLinecap='round' /> </Svg> <TouchableOpacity style={styles.button}> <Text style={{color: '#f5f5f5', fontSize: 35}}>▶</Text> </TouchableOpacity> </SafeAreaView> ); } const styles = StyleSheet.create({ view: { flex: 1, justifyContent: 'center', alignItems: 'center', transform: [ { rotate: '-90deg' }, ], }, button: { position: 'absolute', width: 70, height: 70, left: -150, justifyContent: 'center', alignItems: 'center', backgroundColor: '#3591E7', borderRadius: 100, transform: [ { rotate: '90deg' }, ], } })
额外说明
- 移除了代码中未使用的
AnimatedInput和inputRef相关逻辑,让代码更简洁。 - 你可以根据视觉需求调整
strokeDasharray的两个参数(比如[15, 5]),以及strokeWidth的值,来匹配预期的虚线粗细和间距。
内容的提问来源于stack exchange,提问作者Éniocarlos
相关产品推荐
相关产品推荐

