Advertisement
Guest User

Untitled

a guest
Mar 19th, 2019
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.28 KB | None | 0 0
  1. // @flow
  2.  
  3. import * as React from 'react';
  4. import {
  5. FlatList,
  6. View,
  7. StyleSheet,
  8. Dimensions,
  9. PanResponder
  10. } from 'react-native';
  11. import type { StyleObj } from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
  12.  
  13. type PropsType = {
  14. renderItem: ({ item: any, index: number }) => React.Element<any>,
  15. data: Array<any>,
  16. itemWidth: number,
  17. style: ?StyleObj
  18. };
  19.  
  20. type StateType = {
  21. currentIndex: number
  22. };
  23.  
  24. type EventType = {
  25. nativeEvent: {
  26. contentOffset: {
  27. x: number
  28. }
  29. }
  30. };
  31.  
  32. const { width: SCREENWIDTH } = Dimensions.get('window');
  33.  
  34. class Carousel extends React.Component<PropsType, StateType> {
  35. static defaultProps = {
  36. style: {},
  37. itemWidth: SCREENWIDTH
  38. };
  39.  
  40. panResponder: PanResponder;
  41. carousel: typeof FlatList;
  42.  
  43. currentXPos: number;
  44. currentOffset: number = 0;
  45.  
  46. constructor(props: PropsType) {
  47. super(props);
  48.  
  49. this.state = {
  50. currentIndex: 0
  51. };
  52.  
  53. this.panResponder = PanResponder.create({
  54. onStartShouldSetPanResponder: (evt, gestureState) => true,
  55. onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
  56. onMoveShouldSetPanResponder: (evt, gestureState) => true,
  57. onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
  58. onPanResponderTerminationRequest: () => true,
  59. onPanResponderMove: this.handleMove,
  60. onPanResponderRelease: this.handleRelease
  61. });
  62. }
  63.  
  64. calcOffset = (dx: number) => {
  65. const { currentIndex } = this.state;
  66. const { itemWidth } = this.props;
  67.  
  68. const currentOffset: number = currentIndex * itemWidth;
  69. return currentOffset - dx;
  70. };
  71.  
  72. handleMove = (e: any, { moveX, dx }: any) => {
  73. const offset = this.calcOffset(dx);
  74. this.carousel.scrollToOffset({
  75. offset,
  76. animated: false
  77. });
  78. };
  79.  
  80. handleRelease = (e: any, { moveX, dx }: any) => {
  81. const { itemWidth, data: { length } } = this.props;
  82. const offset = this.calcOffset(dx);
  83. const resolvedIndex = Math.round(offset / itemWidth);
  84. const newIndex =
  85. dx > 0 ? Math.max(resolvedIndex, 0) : Math.min(resolvedIndex, length - 1);
  86.  
  87. this.setState(
  88. {
  89. currentIndex: newIndex
  90. },
  91. () => {
  92. this.carousel.scrollToIndex({
  93. index: newIndex,
  94. animated: true
  95. });
  96. }
  97. );
  98. };
  99.  
  100. getItemLayout = (
  101. data: any,
  102. index: number
  103. ): {
  104. length: number,
  105. offset: number,
  106. index: number
  107. } => {
  108. const { itemWidth } = this.props;
  109. return {
  110. offset: itemWidth * index,
  111. length: itemWidth,
  112. index
  113. };
  114. };
  115.  
  116. setRef = (ref: any): void => {
  117. if (ref) {
  118. this.carousel = ref;
  119. }
  120. };
  121.  
  122. extractKey = (item: any, index: number): string =>
  123. `sw-carousel-item-${index}`;
  124.  
  125. render() {
  126. const { data, renderItem, style } = this.props;
  127.  
  128. return (
  129. <View style={style} {...this.panResponder.panHandlers}>
  130. <FlatList
  131. horizontal
  132. scrollEnabled={false}
  133. showsHorizontalScrollIndicator={false}
  134. data={data}
  135. renderItem={renderItem}
  136. keyExtractor={this.extractKey}
  137. ref={this.setRef}
  138. getItemLayout={this.getItemLayout}
  139. />
  140. </View>
  141. );
  142. }
  143. }
  144.  
  145. export default Carousel;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement