tabView.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //the size of the TabView will follow its parent-container's size.
  2. import * as React from 'react';
  3. import {
  4. View,
  5. Text,
  6. useWindowDimensions,
  7. StyleSheet,
  8. Image,
  9. ImageSourcePropType
  10. } from 'react-native';
  11. import { TabView, SceneMap, TabBar } from 'react-native-tab-view';
  12. import { FlashList } from '@shopify/flash-list';
  13. export interface TabItem {
  14. imgURL: ImageSourcePropType;
  15. date: string;
  16. time: string;
  17. chargeStationName: string;
  18. chargeStationAddress: string;
  19. distance: string;
  20. }
  21. interface TabViewComponentProps {
  22. titles: string[];
  23. tabItems: TabItem[];
  24. }
  25. const TabViewComponent: React.FC<TabViewComponentProps> = ({
  26. titles,
  27. tabItems
  28. }) => {
  29. const layout = useWindowDimensions();
  30. //tab 1
  31. const FirstRoute = () => (
  32. <View style={{ flex: 1, backgroundColor: 'white' }}>
  33. <FlashList
  34. data={tabItems}
  35. renderItem={({ item }) => {
  36. return (
  37. <View style={styles.container}>
  38. <Image style={styles.image} source={item.imgURL} />
  39. <View style={styles.textContainer}>
  40. <Text
  41. style={{
  42. fontWeight: 700,
  43. color: '#02677D',
  44. fontSize: 20
  45. }}
  46. >{`${item.date} - ${item.time}`}</Text>
  47. <Text
  48. style={{
  49. fontWeight: 400,
  50. fontSize: 16,
  51. color: '#222222'
  52. }}
  53. >
  54. {item.chargeStationName}
  55. </Text>
  56. <Text
  57. style={{
  58. fontWeight: 400,
  59. fontSize: 16,
  60. color: '#888888'
  61. }}
  62. >
  63. {item.chargeStationAddress}
  64. </Text>
  65. </View>
  66. <Text
  67. style={{
  68. fontWeight: 400,
  69. fontSize: 16,
  70. color: '#888888',
  71. marginTop: 20,
  72. marginLeft: 10
  73. }}
  74. >
  75. {item.distance}
  76. </Text>
  77. </View>
  78. );
  79. }}
  80. estimatedItemSize={10}
  81. />
  82. </View>
  83. );
  84. //tab 2
  85. const SecondRoute = () => (
  86. <View style={{ flex: 1, backgroundColor: 'white' }} />
  87. );
  88. const renderScene = SceneMap({
  89. firstRoute: FirstRoute,
  90. secondRoute: SecondRoute
  91. });
  92. const [routes] = React.useState([
  93. { key: 'firstRoute', title: titles[0] },
  94. { key: 'secondRoute', title: titles[1] }
  95. ]);
  96. const [index, setIndex] = React.useState(0);
  97. const renderTabBar = (props: any) => (
  98. <TabBar
  99. {...props}
  100. renderLabel={({ route, focused }) => (
  101. <Text
  102. style={{
  103. color: focused ? '#025c72' : '#888888',
  104. fontWeight: focused ? '900' : 'thin',
  105. fontSize: 20
  106. }}
  107. >
  108. {route.title}
  109. </Text>
  110. )}
  111. indicatorStyle={{
  112. backgroundColor: '#025c72'
  113. }}
  114. style={{
  115. backgroundColor: 'white',
  116. borderTopWidth: 4,
  117. borderColor: '#DBE4E8',
  118. elevation: 0,
  119. marginHorizontal: 15,
  120. borderBottomWidth: 0.5
  121. }}
  122. />
  123. );
  124. return (
  125. <TabView
  126. navigationState={{ index, routes }}
  127. renderScene={renderScene}
  128. onIndexChange={setIndex}
  129. initialLayout={{ width: layout.width }}
  130. renderTabBar={renderTabBar}
  131. />
  132. );
  133. };
  134. export default TabViewComponent;
  135. const styles = StyleSheet.create({
  136. container: { flexDirection: 'row' },
  137. image: { width: 100, height: 100, margin: 15, borderRadius: 10 },
  138. textContainer: { flexDirection: 'column', gap: 8, marginTop: 20 }
  139. });