feat:支持身体围度数据展示
This commit is contained in:
131
components/ui/SlidingSelection.tsx
Normal file
131
components/ui/SlidingSelection.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import WheelPickerExpo from 'react-native-wheel-picker-expo';
|
||||
|
||||
export interface SelectionItem {
|
||||
label: string;
|
||||
value: string | number;
|
||||
}
|
||||
|
||||
interface SlidingSelectionProps {
|
||||
items: SelectionItem[];
|
||||
selectedValue?: string | number;
|
||||
onValueChange: (value: string | number, index: number) => void;
|
||||
onConfirm?: (value: string | number, index: number) => void;
|
||||
showConfirmButton?: boolean;
|
||||
confirmButtonText?: string;
|
||||
height?: number;
|
||||
itemTextStyle?: any;
|
||||
selectedIndicatorStyle?: any;
|
||||
}
|
||||
|
||||
export function SlidingSelection({
|
||||
items,
|
||||
selectedValue,
|
||||
onValueChange,
|
||||
onConfirm,
|
||||
showConfirmButton = true,
|
||||
confirmButtonText = '确认',
|
||||
height = 150,
|
||||
itemTextStyle,
|
||||
selectedIndicatorStyle
|
||||
}: SlidingSelectionProps) {
|
||||
const [currentIndex, setCurrentIndex] = useState(() => {
|
||||
if (selectedValue !== undefined) {
|
||||
const index = items.findIndex(item => item.value === selectedValue);
|
||||
return index >= 0 ? index : 0;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
const handleValueChange = (index: number) => {
|
||||
setCurrentIndex(index);
|
||||
const selectedItem = items[index];
|
||||
if (selectedItem) {
|
||||
onValueChange(selectedItem.value, index);
|
||||
}
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
const selectedItem = items[currentIndex];
|
||||
if (selectedItem && onConfirm) {
|
||||
onConfirm(selectedItem.value, currentIndex);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={[styles.pickerContainer, { height }]}>
|
||||
<WheelPickerExpo
|
||||
height={height}
|
||||
width={300}
|
||||
initialSelectedIndex={currentIndex}
|
||||
items={items.map(item => ({ label: item.label, value: item.value }))}
|
||||
onChange={({ item, index }) => handleValueChange(index)}
|
||||
backgroundColor="transparent"
|
||||
haptics
|
||||
/>
|
||||
</View>
|
||||
|
||||
{showConfirmButton && (
|
||||
<TouchableOpacity
|
||||
style={styles.confirmButton}
|
||||
onPress={handleConfirm}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<Text style={styles.confirmButtonText}>{confirmButtonText}</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
},
|
||||
pickerContainer: {
|
||||
width: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
picker: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
itemText: {
|
||||
fontSize: 16,
|
||||
color: '#333',
|
||||
fontWeight: '500',
|
||||
},
|
||||
selectedIndicator: {
|
||||
backgroundColor: 'rgba(74, 144, 226, 0.1)',
|
||||
borderRadius: 8,
|
||||
},
|
||||
confirmButton: {
|
||||
backgroundColor: '#4A90E2',
|
||||
paddingHorizontal: 32,
|
||||
paddingVertical: 12,
|
||||
borderRadius: 20,
|
||||
marginTop: 16,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 2,
|
||||
},
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 4,
|
||||
elevation: 4,
|
||||
},
|
||||
confirmButtonText: {
|
||||
color: 'white',
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user