tabView.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. nestedScrollEnabled={true}
  35. data={tabItems}
  36. renderItem={({ item }) => {
  37. return (
  38. <View style={styles.container}>
  39. <Image style={styles.image} source={item.imgURL} />
  40. <View style={styles.textContainer}>
  41. <Text
  42. style={{
  43. fontWeight: 700,
  44. color: '#02677D',
  45. fontSize: 20
  46. }}
  47. >{`${item.date} - ${item.time}`}</Text>
  48. <Text
  49. style={{
  50. fontWeight: 400,
  51. fontSize: 16,
  52. color: '#222222'
  53. }}
  54. >
  55. {item.chargeStationName}
  56. </Text>
  57. <Text
  58. style={{
  59. fontWeight: 400,
  60. fontSize: 16,
  61. color: '#888888'
  62. }}
  63. >
  64. {item.chargeStationAddress}
  65. </Text>
  66. </View>
  67. <Text
  68. style={{
  69. fontWeight: 400,
  70. fontSize: 16,
  71. color: '#888888',
  72. marginTop: 20,
  73. marginLeft: 10
  74. }}
  75. >
  76. {item.distance}
  77. </Text>
  78. </View>
  79. );
  80. }}
  81. estimatedItemSize={10}
  82. />
  83. </View>
  84. );
  85. //tab 2
  86. const SecondRoute = () => (
  87. <View style={{ flex: 1, backgroundColor: 'white' }} />
  88. );
  89. const renderScene = SceneMap({
  90. firstRoute: FirstRoute,
  91. secondRoute: SecondRoute
  92. });
  93. const [routes] = React.useState([
  94. { key: 'firstRoute', title: titles[0] },
  95. { key: 'secondRoute', title: titles[1] }
  96. ]);
  97. const [index, setIndex] = React.useState(0);
  98. const renderTabBar = (props: any) => (
  99. <TabBar
  100. {...props}
  101. renderLabel={({ route, focused }) => (
  102. <Text
  103. style={{
  104. color: focused ? '#025c72' : '#888888',
  105. fontWeight: focused ? '900' : 'thin',
  106. fontSize: 20
  107. }}
  108. >
  109. {route.title}
  110. </Text>
  111. )}
  112. indicatorStyle={{
  113. backgroundColor: '#025c72'
  114. }}
  115. style={{
  116. backgroundColor: 'white',
  117. // borderTopWidth: 4,
  118. borderColor: '#DBE4E8',
  119. elevation: 0,
  120. marginHorizontal: 15,
  121. borderBottomWidth: 0.5
  122. }}
  123. />
  124. );
  125. return (
  126. <TabView
  127. navigationState={{ index, routes }}
  128. renderScene={renderScene}
  129. onIndexChange={setIndex}
  130. initialLayout={{ width: layout.width }}
  131. renderTabBar={renderTabBar}
  132. />
  133. );
  134. };
  135. export default TabViewComponent;
  136. const styles = StyleSheet.create({
  137. container: { flexDirection: 'row' },
  138. image: { width: 100, height: 100, margin: 15, borderRadius: 10 },
  139. textContainer: { flexDirection: 'column', gap: 8, marginTop: 20 }
  140. });