You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:38:15