ReactNative中实现可拖拽的温度计组件
要实现一个可拖拽的温度计,我们可以结合 React Native 的拖拽机制和温度计视觉效果。下面是一个完整的实现方案,使用 PanResponder
处理拖拽逻辑,并通过状态控制温度值:
import React, { useRef, useState } from 'react';
import { View, PanResponder, StyleSheet, Text, Dimensions } from 'react-native';// 获取屏幕尺寸
const { width } = Dimensions.get('window');const DraggableThermometer = () => {// 温度状态 (范围: 0-100°C)const [temperature, setTemperature] = useState(25);// 温度计高度const thermometerHeight = 300;// 滑块位置const [sliderPosition, setSliderPosition] = useState({y: thermometerHeight - (temperature / 100) * thermometerHeight});// 偏移量记录const offset = useRef({ y: 0 });// 创建PanResponder处理拖拽const panResponder = PanResponder.create({// 允许响应触摸事件onStartShouldSetPanResponder: () => true,onMoveShouldSetPanResponder: () => true,// 触摸开始时记录偏移onPanResponderGrant: (e, gesture) => {offset.current.y = sliderPosition.y - gesture.dy;},// 触摸移动时更新位置和温度onPanResponderMove: (e, gesture) => {// 计算新位置,限制在温度计范围内let newY = offset.current.y + gesture.dy;newY = Math.max(0, Math.min(newY, thermometerHeight));// 更新滑块位置setSliderPosition({ y: newY });// 根据位置计算温度 (0-100°C)const newTemperature = Math.round(100 - (newY / thermometerHeight) * 100);setTemperature(newTemperature);}});// 计算温度柱高度const temperatureBarHeight = (temperature / 100) * thermometerHeight;return (<View style={styles.container}>{/* 温度显示 */}<Text style={styles.tempText}>{temperature}°C</Text>{/* 温度计容器 */}<View style={[styles.thermometer, { height: thermometerHeight }]}>{/* 温度刻度 */}<View style={styles.scale}>{[0, 20, 40, 60, 80, 100].map((value) => (<View key={value}style={[styles.tick,{ top: thermometerHeight - (value / 100) * thermometerHeight }]}><Text style={styles.tickText}>{value}</Text></View>))}</View>{/* 温度柱 */}<View style={styles.tube}><View style={[styles.temperatureBar,{ height: temperatureBarHeight,bottom: 0}]}/></View>{/* 可拖拽滑块 */}<Viewstyle={[styles.slider,{ top: sliderPosition.y }]}{...panResponder.panHandlers}/></View>{/* 温度范围提示 */}<View style={styles.labels}><Text>低温</Text><Text>高温</Text></View></View>);
};const styles = StyleSheet.create({container: {alignItems: 'center',paddingVertical: 40},tempText: {fontSize: 40,fontWeight: 'bold',marginBottom: 20,color: '#333'},thermometer: {width: 60,position: 'relative',alignItems: 'center'},tube: {width: 20,height: '100%',borderWidth: 2,borderColor: '#666',borderRadius: 10,backgroundColor: 'transparent',position: 'relative',overflow: 'hidden'},temperatureBar: {width: '100%',backgroundColor: '#ff6b6b',position: 'absolute',transitionProperty: 'height',transitionDuration: '200ms'},slider: {width: 40,height: 15,backgroundColor: '#4a6fff',borderRadius: 3,position: 'absolute',left: (60 - 40) / 2,transform: [{ translateY: -7.5 }], // 居中对齐borderWidth: 2,borderColor: '#333'},scale: {position: 'absolute',right: -30,height: '100%',width: 30},tick: {position: 'absolute',width: 10,height: 2,backgroundColor: '#666',right: 0},tickText: {position: 'absolute',right: 12,fontSize: 12,color: '#666',transform: [{ translateY: -6 }]},labels: {width: 200,flexDirection: 'row',justifyContent: 'space-between',marginTop: 10}
});export default DraggableThermometer;
这个可拖拽温度计组件的特点:
-
核心功能:
- 通过拖拽滑块调节温度(范围 0-100°C)
- 实时显示当前温度值
- 带有温度刻度标记,直观展示温度位置
-
实现细节:
- 使用
PanResponder
处理拖拽手势 - 将滑块位置映射为温度值(位置越高,温度越低)
- 限制滑块在温度计范围内移动,防止超出边界
- 温度变化平滑且有数值显示
- 使用
-
UI 设计:
- 包含温度计主体、温度柱、可拖拽滑块
- 右侧有温度刻度标记
- 底部有高低温提示
- 温度柱颜色使用渐变色效果(红色表示高温)
使用时,只需将该组件导入并添加到你的视图中即可。你可以根据需要调整样式,如温度计高度、颜色、温度范围等。如果需要摄氏度/华氏度切换,可以添加一个切换按钮并修改温度计算逻辑。