YH_ViewPager.js 4.1 KB
/**
 * Description:
 *
 * Author:  Bruce.Lu
 * Version: 1.0
 * Created on 2017/2/23.
 */
import React from 'react';
import ReactNative from 'react-native';

let {
    requireNativeComponent,
    View,
} = ReactNative;
var dismissKeyboard = require('dismissKeyboard');

let YH_ViewPagerView = requireNativeComponent('YH_ViewPager', null);

var UIManager = require('UIManager');

type Event = Object;
var VIEWPAGER_REF = 'viewPager';

export type ViewPagerScrollState = $Enum<{
    idle: string,
    dragging: string,
    settling: string,
}>;

export default class YH_ViewPager extends React.Component {
    props: {
        initialPage?: number,
        onPageScroll?: Function,
        onPageScrollStateChanged?: Function,
        onPageSelected?: Function,
        pageMargin?: number,
        keyboardDismissMode?: 'none' | 'on-drag',
        scrollEnabled?: boolean,
    };

    static propTypes = {
        ...View.propTypes,
        initialPage: React.PropTypes.number,
        onPageScroll: React.PropTypes.func,
        onPageScrollStateChanged: React.PropTypes.func,
        onPageSelected: React.PropTypes.func,
        pageMargin: React.PropTypes.number,
        keyboardDismissMode: React.PropTypes.oneOf([
            'none', // default
            'on-drag',
        ]),
        scrollEnabled: React.PropTypes.bool,
    };

    constructor(props) {
        super(props);
    }

    componentDidMount() {
        if (this.props.initialPage != null) {
            this.setPageWithoutAnimation(this.props.initialPage);
        }
    }

    _childrenWithOverridenStyle = (): Array => {
        // Override styles so that each page will fill the parent. Native component
        // will handle positioning of elements, so it's not important to offset
        // them correctly.
        return React.Children.map(this.props.children, function(child) {
            if (!child) {
                return null;
            }
            var newProps = {
                ...child.props,
                style: [child.props.style, {
                    position: 'absolute',
                    left: 0,
                    top: 0,
                    right: 0,
                    bottom: 0,
                    width: undefined,
                    height: undefined,
                }],
                collapsable: false,
            };
            if (child.type &&
                child.type.displayName &&
                (child.type.displayName !== 'RCTView') &&
                (child.type.displayName !== 'View')) {
                console.warn('Each ViewPager child must be a <View>. Was ' + child.type.displayName);
            }
            return React.createElement(child.type, newProps);
        });
    };

    _onPageScroll = (e: Event) => {
        if (this.props.onPageScroll) {
            this.props.onPageScroll(e);
        }
        if (this.props.keyboardDismissMode === 'on-drag') {
            dismissKeyboard();
        }
    };

    _onPageScrollStateChanged = (e: Event) => {
        if (this.props.onPageScrollStateChanged) {
            this.props.onPageScrollStateChanged(e.nativeEvent.pageScrollState);
        }
    };

    _onPageSelected = (e: Event) => {
        if (this.props.onPageSelected) {
            this.props.onPageSelected(e);
        }
    };

    setPage = (selectedPage: number) => {
        UIManager.dispatchViewManagerCommand(
            ReactNative.findNodeHandle(this),
            UIManager.AndroidViewPager.Commands.setPage,
            [selectedPage],
        );
    };

    setPageWithoutAnimation = (selectedPage: number) => {
        UIManager.dispatchViewManagerCommand(
            ReactNative.findNodeHandle(this),
            UIManager.AndroidViewPager.Commands.setPageWithoutAnimation,
            [selectedPage],
        );
    };


    render() {
        return (<YH_ViewPagerView
            {...this.props}
            ref={VIEWPAGER_REF}
            style={this.props.style}
            onPageScroll={this._onPageScroll}
            onPageScrollStateChanged={this._onPageScrollStateChanged}
            onPageSelected={this._onPageSelected}
            children={this._childrenWithOverridenStyle()}
        />);
    }
}