Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // @flow
- import * as React from 'react';
- import {
- FlatList,
- View,
- StyleSheet,
- Dimensions,
- PanResponder
- } from 'react-native';
- import type { StyleObj } from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
- type PropsType = {
- renderItem: ({ item: any, index: number }) => React.Element<any>,
- data: Array<any>,
- itemWidth: number,
- style: ?StyleObj
- };
- type StateType = {
- currentIndex: number
- };
- type EventType = {
- nativeEvent: {
- contentOffset: {
- x: number
- }
- }
- };
- const { width: SCREENWIDTH } = Dimensions.get('window');
- class Carousel extends React.Component<PropsType, StateType> {
- static defaultProps = {
- style: {},
- itemWidth: SCREENWIDTH
- };
- panResponder: PanResponder;
- carousel: typeof FlatList;
- currentXPos: number;
- currentOffset: number = 0;
- constructor(props: PropsType) {
- super(props);
- this.state = {
- currentIndex: 0
- };
- this.panResponder = PanResponder.create({
- onStartShouldSetPanResponder: (evt, gestureState) => true,
- onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
- onMoveShouldSetPanResponder: (evt, gestureState) => true,
- onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
- onPanResponderTerminationRequest: () => true,
- onPanResponderMove: this.handleMove,
- onPanResponderRelease: this.handleRelease
- });
- }
- calcOffset = (dx: number) => {
- const { currentIndex } = this.state;
- const { itemWidth } = this.props;
- const currentOffset: number = currentIndex * itemWidth;
- return currentOffset - dx;
- };
- handleMove = (e: any, { moveX, dx }: any) => {
- const offset = this.calcOffset(dx);
- this.carousel.scrollToOffset({
- offset,
- animated: false
- });
- };
- handleRelease = (e: any, { moveX, dx }: any) => {
- const { itemWidth, data: { length } } = this.props;
- const offset = this.calcOffset(dx);
- const resolvedIndex = Math.round(offset / itemWidth);
- const newIndex =
- dx > 0 ? Math.max(resolvedIndex, 0) : Math.min(resolvedIndex, length - 1);
- this.setState(
- {
- currentIndex: newIndex
- },
- () => {
- this.carousel.scrollToIndex({
- index: newIndex,
- animated: true
- });
- }
- );
- };
- getItemLayout = (
- data: any,
- index: number
- ): {
- length: number,
- offset: number,
- index: number
- } => {
- const { itemWidth } = this.props;
- return {
- offset: itemWidth * index,
- length: itemWidth,
- index
- };
- };
- setRef = (ref: any): void => {
- if (ref) {
- this.carousel = ref;
- }
- };
- extractKey = (item: any, index: number): string =>
- `sw-carousel-item-${index}`;
- render() {
- const { data, renderItem, style } = this.props;
- return (
- <View style={style} {...this.panResponder.panHandlers}>
- <FlatList
- horizontal
- scrollEnabled={false}
- showsHorizontalScrollIndicator={false}
- data={data}
- renderItem={renderItem}
- keyExtractor={this.extractKey}
- ref={this.setRef}
- getItemLayout={this.getItemLayout}
- />
- </View>
- );
- }
- }
- export default Carousel;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement