求助:如何开发带动画的React Native垂直时间线进度条
嘿,我来帮你搞定这个带动画的React Native垂直时间线进度条!先看你附的效果,核心就是要实现进度条的填充动画和节点状态的动态变化对吧?我直接给你拆成可落地的步骤和代码,拿来就能用~
核心思路拆解
- 先搭基础结构:左侧是垂直的背景线条+动态进度条+状态节点,右侧对应每个节点的文字描述
- 动画部分分两块:进度条的高度变化动画(随当前进度比例调整),以及节点的缩放/颜色切换动画(标记完成/当前状态)
具体代码实现
我们用React Native自带的Animated API就能搞定,不需要额外装第三方库,先上组件代码:
1. 导入依赖
import React, { useEffect, useRef, useState } from 'react'; import { View, Text, StyleSheet, Animated, Easing, Button } from 'react-native';
2. 定义时间线组件
const TimeLineProgress = ({ currentStep, steps }) => { // 用于控制进度条动画的变量 const progressAnim = useRef(new Animated.Value(0)).current; // 当当前步骤变化时,触发进度条动画 useEffect(() => { // 计算当前进度比例:当前步骤数 / 总步骤数 const progressRatio = currentStep / steps.length; Animated.timing(progressAnim, { toValue: progressRatio, duration: 800, // 动画时长,可自定义 easing: Easing.out(Easing.ease), // 缓动效果,让动画更自然 useNativeDriver: false, // 因为要修改height属性,不能用native driver }).start(); }, [currentStep, steps.length]); return ( <View style={styles.container}> {/* 左侧时间线区域 */} <View style={styles.timelineWrapper}> {/* 灰色背景线条 */} <View style={styles.timelineBgLine} /> {/* 动态填充的绿色进度条 */} <Animated.View style={[ styles.timelineProgressLine, { height: progressAnim.interpolate({ inputRange: [0, 1], outputRange: ['0%', '100%'], }), }, ]} /> {/* 节点列表 */} {steps.map((step, index) => { const isCompleted = index < currentStep; const isCurrent = index === currentStep; return ( <View key={index} style={styles.nodeWrapper}> <Animated.View style={[ styles.node, { backgroundColor: isCompleted ? '#2ecc71' : isCurrent ? '#3498db' : '#bdc3c7', // 节点完成时的缩放动画 transform: [ { scale: progressAnim.interpolate({ inputRange: [index / steps.length, (index + 1) / steps.length], outputRange: [1, 1.2], extrapolate: 'clamp', // 超出范围保持对应值 }), }, ], }, ]} /> </View> ); })} </View> {/* 右侧步骤文字区域 */} <View style={styles.stepsTextWrapper}> {steps.map((step, index) => { const isCompleted = index < currentStep; return ( <Text key={index} style={[ styles.stepText, { color: isCompleted ? '#2ecc71' : '#7f8c8d' }, ]} > {step.text} </Text> ); })} </View> </View> ); };
3. 样式定义
const styles = StyleSheet.create({ container: { flexDirection: 'row', alignItems: 'flex-start', paddingHorizontal: 20, paddingVertical: 10, width: '100%', }, timelineWrapper: { position: 'relative', alignItems: 'center', marginRight: 20, }, timelineBgLine: { position: 'absolute', top: 0, bottom: 0, width: 2, backgroundColor: '#ecf0f1', }, timelineProgressLine: { position: 'absolute', top: 0, width: 2, backgroundColor: '#2ecc71', }, nodeWrapper: { height: 60, // 每个节点的垂直间距,可根据需求调整 alignItems: 'center', justifyContent: 'center', }, node: { width: 16, height: 16, borderRadius: 8, borderWidth: 2, borderColor: '#fff', shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.2, shadowRadius: 2, elevation: 2, // Android端阴影效果 }, stepsTextWrapper: { flex: 1, justifyContent: 'space-between', height: steps.length * 60, // 和节点高度保持一致 }, stepText: { fontSize: 14, paddingVertical: 18, lineHeight: 20, }, });
4. 使用示例
// 在你的页面中调用组件 const App = () => { const [currentStep, setCurrentStep] = useState(2); // 自定义你的步骤数据 const orderSteps = [ { text: '订单已创建' }, { text: '商家已接单' }, { text: '商品已出库' }, { text: '正在配送' }, { text: '已送达' }, ]; return ( <View style={{ flex: 1, justifyContent: 'center', paddingTop: 50 }}> <TimeLineProgress currentStep={currentStep} steps={orderSteps} /> {/* 测试用的按钮,点击切换进度 */} <View style={{ marginTop: 30, paddingHorizontal: 20 }}> <Button title="下一步" onPress={() => setCurrentStep(prev => Math.min(prev + 1, orderSteps.length))} /> <Button title="上一步" onPress={() => setCurrentStep(prev => Math.max(prev - 1, 0))} style={{ marginTop: 10 }} /> </View> </View> ); };
自定义调整小贴士
- 动画效果:可以修改
duration调整动画时长,或者换Easing函数(比如Easing.inOut(Easing.quad))让动画曲线更贴合你的需求 - 节点样式:如果想把完成的节点换成对勾图标,可以用
react-native-vector-icons导入图标组件,替换掉当前的实心圆 - 进度方向:如果需要进度条从下往上填充,只需要把进度条的
position改成bottom,并把interpolate的outputRange改成['100%', '0%'] - 颜色主题:把代码里的颜色值换成你的设计稿配色就行,比如把完成色改成品牌蓝
内容的提问来源于stack exchange,提问作者Akash Jain
相关产品推荐
相关产品推荐

