import React, {useEffect, useRef, useState} from 'react'; import { FlatList, StyleProp, StyleSheet, Text, TextStyle, TouchableOpacity, View, ViewStyle, } from 'react-native'; import {useDip} from 'react-native-x-utils'; import {TabType} from '../../types'; export interface TabsProps { /** 整体样式 */ style?: StyleProp; /** 文字和指示器之间的距离 */ distanceTextDot?: number; /** 标签之间的距离 */ distanceBetweenTabs?: number; /** 激活和未激活 Tab 的样式 */ /** 标题样式 */ activeTextStyle?: StyleProp; inactiveTextStyle?: StyleProp; /** 指示器样式 */ activeDotStyle?: StyleProp; inactiveDotStyle?: StyleProp; /** 激活 Tab 的 Index */ activeIndex?: number; /** 数据源,暂不支持泛型 ,没必要 */ tabLabels: string[]; /** Tab 的点击事件 */ onTabPress: (item: TabType) => void; } const Tabs: React.FC = props => { const { onTabPress, style, activeTextStyle, inactiveTextStyle, activeDotStyle, inactiveDotStyle, distanceBetweenTabs = 12, distanceTextDot = 8, activeIndex = 0, tabLabels = [], } = props; const [datas, setDatas] = useState([]); let list = useRef(); useEffect(() => { setDatas( tabLabels.map((item, index) => ({name: item, index, select: index == 0})), ); return function () {}; }, [tabLabels]); useEffect(() => { indexUpdater(activeIndex); return () => {}; }, [activeIndex]); const indexUpdater = (index: number) => { let _datas = [...datas]; for (let i = 0; i < _datas.length; i++) { _datas[i].select = index == _datas[i].index; } setDatas(_datas); _datas.length > 0 && list.current.scrollToIndex({index, animated: true, viewPosition: 0.5}); }; return ( (list.current = ref)} showsHorizontalScrollIndicator={false} horizontal={true} bounces={false} data={datas} renderItem={info => { let {item} = info; let {index, name, select} = item; return ( { indexUpdater(index); onTabPress(item); }} style={{ alignItems: 'center', paddingHorizontal: distanceBetweenTabs / 2, }}> {name} ); }} keyExtractor={(item, index) => `${index}`} /> ); }; const styles = StyleSheet.create({ view: { backgroundColor: 'white', paddingHorizontal: 12, flexDirection: 'row', height: useDip(56), alignItems: 'flex-end', paddingBottom: 4, }, activeTextStyle: { fontSize: useDip(16), fontWeight: 'bold', color: '#987123', }, inactiveTextStyle: { fontSize: useDip(16), color: '#666', }, activeDotStyle: { height: 4, width: 4, borderRadius: 2, backgroundColor: '#987123', }, inactiveDotStyle: { height: 4, width: 4, }, }); export default Tabs;