import * as React from 'react';
import {
NativeScrollEvent,
NativeSyntheticEvent,
ScrollView,
StyleSheet,
Text,
View,
} from 'react-native';
import { picker } from '../../_styles/themes/default.components';
import { innerScaleSize } from '../../_styles/themes/responsive';
interface IMDPickerColumnProps {
itemHeight?: number;
onPickerSelected: (
selectIndex: number,
selectContext: any,
columnIndex: number
) => void;
column: any[];
width: number;
offsetY: number;
columnIndex: number;
selectIndex: number;
invalidItemIndexs: number[];
}
interface IMDPickerColumnState {
selectIndex: number;
}
export default class PickerColumn extends React.Component<
IMDPickerColumnProps,
IMDPickerColumnState
> {
public static defaultProps = {
itemHeight: innerScaleSize(40 * 2),
onPickerSelected: null,
invalidItemIndexs: [],
};
constructor (props: IMDPickerColumnProps) {
super(props);
this.state = {
selectIndex: 0,
};
}
private selectIndex = 0;
private oldIndex = 0;
private isDragAnima: boolean = false;
private scroller: ScrollView | null = null;
private isNewProps: boolean = false;
public componentWillReceiveProps (nextProps: IMDPickerColumnProps) {
if (
JSON.stringify(nextProps.column) !== JSON.stringify(this.props.column) ||
nextProps.selectIndex !== this.selectIndex
) {
this.selectIndex = this.checkValidIndex(nextProps.selectIndex, nextProps);
this.isNewProps = true;
this.setState({
selectIndex: nextProps.selectIndex,
});
}
}
public componentWillMount () {
this.selectIndex = this.checkValidIndex(this.props.selectIndex, this.props);
this.isNewProps = true;
this.setState({
selectIndex: this.props.selectIndex,
});
}
public componentDidMount () {
this.scrollTopIndex(this.selectIndex);
}
public componentDidUpdate () {
this.scrollTopIndex(this.selectIndex);
}
public render () {
return (
{
this.scroller = scrollView;
}}
style={[styles.column, { width: this.props.width }]}
removeClippedSubviews={true}
automaticallyAdjustContentInsets={false}
showsVerticalScrollIndicator={false}
contentInset={{
top: this.props.offsetY,
left: 0,
bottom: this.props.offsetY,
right: 0,
}}
contentOffset={{ x: 0, y: -this.props.offsetY }}
onScrollBeginDrag={() => {
this.onScrollBeginDrag();
}}
onScrollEndDrag={(e: NativeSyntheticEvent) => {
this.onScrollEndDrag(e);
}}
onMomentumScrollEnd={(e: NativeSyntheticEvent) => {
this.onMomentumScrollEnd(e);
}}
onMomentumScrollBegin={(e: NativeSyntheticEvent) => {
this.onMomentumScrollBegin(e);
}}
>
{this.renderList(this.props.column)}
);
}
private renderList (column: any[]) {
return column.map((item, index) => {
return this.renderItem(item, index);
});
}
private renderItem (item: any, index: number) {
return (
{item.text || item.label}
);
}
private onScrollBeginDrag () {
// console.log('ttttpicker','onScrollBeginDrag',this.props.columnIndex,this.isDragAnima)
}
private onScrollEndDrag (e: NativeSyntheticEvent) {
const pIndex = this.caculateScrollIndex(e);
setTimeout(() => {
if (!this.isDragAnima) {
this.updateSelectIndex(pIndex);
this.props.onPickerSelected(
this.selectIndex,
this.getActiveValue(),
this.props.columnIndex
);
}
}, 200);
}
private onMomentumScrollBegin (e: NativeSyntheticEvent) {
this.isDragAnima = true;
}
private onMomentumScrollEnd (e: NativeSyntheticEvent) {
const pIndex = this.caculateScrollIndex(e);
setTimeout(() => {
if (this.isDragAnima) {
this.isDragAnima = false;
this.updateSelectIndex(pIndex);
this.props.onPickerSelected(
this.selectIndex,
this.getActiveValue(),
this.props.columnIndex
);
}
}, 200);
}
private scrollToPisiton (x: number, y: number) {
if (!this.isNewProps && Math.abs(this.selectIndex - this.oldIndex) < 2) {
this.scroller!.scrollResponderScrollTo({ x, y, animated: true });
} else {
if (this.isNewProps) {
this.isNewProps = false;
}
this.scroller!.scrollResponderScrollTo({ x, y, animated: false });
}
}
private scrollTopIndex (index: number) {
this.scrollToPisiton(0, index * this.props.itemHeight! - this.props.offsetY);
}
private caculateScrollIndex (e: NativeSyntheticEvent) {
let pIndex = Math.round(
(e.nativeEvent.contentOffset.y + this.props.offsetY) /
this.props.itemHeight!
);
if (pIndex < 0) {
pIndex = 0;
} else if (pIndex >= this.props.column.length) {
pIndex = this.props.column.length - 1;
}
return pIndex;
}
private updateSelectIndex (index: number) {
this.oldIndex = this.selectIndex;
this.selectIndex = this.checkValidIndex(index, this.props);
this.setState({
selectIndex: this.selectIndex,
});
}
private checkValidIndex (index: number, props: IMDPickerColumnProps) {
while (props.invalidItemIndexs.indexOf(index) >= 0) {
++index;
}
if (index >= props.column.length) {
index = 0;
}
return index;
}
private getActiveValue () {
const item: any = this.props.column[this.selectIndex];
return item;
}
}
const styles = StyleSheet.create({
column: {
display: 'flex',
flexDirection: 'column',
overflow: 'hidden',
},
item: {
width: '100%',
alignItems: 'center',
justifyContent: 'center',
},
text: {
textAlign: 'center',
fontSize: picker.fontSize,
marginLeft: 10,
marginRight: 10,
},
});