我正在开发一个 React Native 项目,我需要显示一个概述非圆形视图的进度指示器。
我尝试使用react-native-svg和Circle组件来创建一个圆形进度指示器,但它没有按照我想要的方式工作。
我需要进度指示器来适应椭圆形或圆角矩形形状。
这是我当前使用基本 React Native 组件的方法的简化版本:https://snack.expo.dev/@audn/progress-border
我想要做什么:
到目前为止我所拥有的:
import { TouchableOpacity, Text, View, StyleSheet } from 'react-native';
import moment from 'moment';
import Svg, { Circle } from 'react-native-svg';
const DateComponent = () => {
const date = moment(new Date());
const dayName = date.format('dd').charAt(0);
const dayNumber = date.format('D');
const isFutureDate = date.isAfter(moment(), 'day');
const progress = 0.75;
const radius = 35;
const strokeWidth = 2;
const circumference = 2 * Math.PI * radius;
return (
<TouchableOpacity style={styles.container}>
<View style={styles.wrapper}>
<Svg height="70" width="70" viewBox="0 0 70 70">
<Circle
cx="35"
cy="35"
r={radius}
stroke="gray"
strokeWidth={strokeWidth}
fill="none"
opacity={0.2}
/>
<Circle
cx="35"
cy="35"
r={radius}
stroke="green"
strokeWidth={strokeWidth}
fill="none"
strokeDasharray={`${circumference} ${circumference}`}
strokeDashoffset={(1 - progress) * circumference}
strokeLinecap="round"
transform="rotate(-90, 35, 35)"
/>
</Svg>
<View style={styles.card}>
<Text style={styles.dayText}>{dayName}</Text>
<Text style={[styles.dateText, { color: isFutureDate ? '#757575' : 'black' }]}>
{dayNumber}
</Text>
</View>
</View>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
},
wrapper: {
justifyContent: 'center',
alignItems: 'center',
},
card: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 35,
height: 70,
width: 70,
},
dayText: {
fontSize: 14,
color: '#757575',
},
dateText: {
fontSize: 18,
fontWeight: 'bold',
},
});
export default DateComponent;
我画了一个简单的
SVG
文件,然后将其切换到到您的代码中...这个解决方案对您来说合适吗?
import React from 'react';
import { TouchableOpacity, StyleSheet, View } from 'react-native';
import Svg, { Rect, Text as SvgText } from 'react-native-svg';
import moment from 'moment';
const DateComponent = () => {
const date = moment(new Date());
const dayName = date.format('dd').charAt(0);
const dayNumber = date.format('D');
const isFutureDate = date.isAfter(moment(), 'day');
const progress = 0.75;
const radius = 30;
const strokeWidth = 3;
const rectWidth = 60;
const rectHeight = 80;
const circumference = 2 * Math.PI * radius;
const progressLength = progress * circumference;
return (
<View style={styles.screen}>
<TouchableOpacity style={styles.container}>
<Svg width="70" height="100" viewBox="0 0 70 100">
<Rect
x="5"
y="10"
width={rectWidth}
height={rectHeight}
rx={radius}
ry={radius}
fill="black"
stroke="gray"
strokeWidth={strokeWidth}
opacity={0.2}
/>
<Rect
x="5"
y="10"
width={rectWidth}
height={rectHeight}
rx={radius}
ry={radius}
fill="none"
stroke="green"
strokeWidth={strokeWidth}
strokeDasharray={`${progressLength} ${circumference}`}
strokeLinecap="round"
/>
<SvgText
x="35"
y="40"
textAnchor="middle"
fill="#858585"
fontSize="20"
fontFamily="Arial"
>
{dayName}
</SvgText>
<SvgText
x="35"
y="75"
textAnchor="middle"
fill={isFutureDate ? '#757575' : 'white'}
fontSize="20"
fontFamily="Arial"
>
{dayNumber}
</SvgText>
</Svg>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f5f5f5',
},
container: {
justifyContent: 'center',
alignItems: 'center',
width: 70,
height: 100,
},
});
export default DateComponent;