feat: 优化数据加载逻辑,添加应用状态监听以刷新统计数据;为步数卡片添加动画效果

This commit is contained in:
2025-08-30 23:07:14 +08:00
parent 6bdfda9fd3
commit 4bb0576d92
2 changed files with 77 additions and 18 deletions

View File

@@ -1,9 +1,10 @@
import React, { useMemo } from 'react';
import React, { useMemo, useRef, useEffect } from 'react';
import {
StyleSheet,
Text,
View,
ViewStyle
ViewStyle,
Animated
} from 'react-native';
import { HourlyStepData } from '@/utils/health';
@@ -23,6 +24,11 @@ const StepsCard: React.FC<StepsCardProps> = ({
hourlySteps,
style
}) => {
// 为每个柱体创建独立的动画值
const animatedValues = useRef(
Array.from({ length: 24 }, () => new Animated.Value(0))
).current;
// 计算柱状图数据
const chartData = useMemo(() => {
if (!hourlySteps || hourlySteps.length === 0) {
@@ -42,6 +48,26 @@ const StepsCard: React.FC<StepsCardProps> = ({
// 获取当前小时
const currentHour = new Date().getHours();
// 触发柱体动画
useEffect(() => {
if (chartData && chartData.length > 0) {
// 重置所有动画值
animatedValues.forEach(animValue => animValue.setValue(0));
// 同时启动所有柱体的弹性动画,有步数的柱体才执行动画
chartData.forEach((data, index) => {
if (data.steps > 0) {
Animated.spring(animatedValues[index], {
toValue: 1,
tension: 150,
friction: 8,
useNativeDriver: false,
}).start();
}
});
}
}, [chartData, animatedValues]);
return (
<View style={[styles.container, style]}>
{/* 标题和步数显示 */}
@@ -58,14 +84,28 @@ const StepsCard: React.FC<StepsCardProps> = ({
const isActive = data.steps > 0;
const isCurrent = index <= currentHour;
// 动画变换缩放从0到实际高度
const animatedScale = animatedValues[index].interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
});
// 动画变换透明度从0到1
const animatedOpacity = animatedValues[index].interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
});
return (
<View
<Animated.View
key={`bar-${index}`}
style={[
styles.chartBar,
{
height: data.height || 2, // 最小高度2px
backgroundColor: isCurrent && isActive ? '#FFC365' : '#FFEBCB',
transform: [{ scaleY: animatedScale }],
opacity: animatedOpacity,
}
]}
/>