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: string,
columnIndex: number
) => void;
column: [];
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: 2,
};
}
private selectIndex = 0;
private realIndex = 0;
private oldIndex = 0;
private isDragAnima: boolean = false;
private scroller: ScrollView | null = null;
private isNewProps: boolean = false;
private columnValue: any[] = [];
public componentWillReceiveProps (nextProps: IMDPickerColumnProps) {
if (
JSON.stringify(nextProps.column) !== JSON.stringify(this.props.column) ||
nextProps.selectIndex !== this.realIndex
) {
this.realIndex = this.checkValidIndex(nextProps.selectIndex, nextProps);
this.selectIndex = this.realIndex + 2;
this.isNewProps = true;
this.setState({
selectIndex: nextProps.selectIndex + 2,
});
this.initColumnValue(nextProps.column);
}
}
public componentWillMount () {
this.initColumnValue(this.props.column);
this.isNewProps = true;
this.realIndex = this.checkValidIndex(this.props.selectIndex, this.props);
this.selectIndex = this.realIndex + 2;
this.setState({
selectIndex: this.selectIndex,
});
}
public componentDidMount () {
setTimeout(() => {
this.scrollTopIndex(this.realIndex);
}, 30);
}
public componentDidUpdate () {
this.scrollTopIndex(this.realIndex);
}
public render () {
return (
{
this.scroller = scrollView;
}}
style={[styles.column, { width: this.props.width }]}
removeClippedSubviews={true}
automaticallyAdjustContentInsets={false}
showsVerticalScrollIndicator={false}
onScrollBeginDrag={() => {
this.onScrollBeginDrag();
}}
onScrollEndDrag={(e: NativeSyntheticEvent) => {
this.onScrollEndDrag(e);
}}
onMomentumScrollEnd={(e: NativeSyntheticEvent) => {
this.onMomentumScrollEnd(e);
}}
onMomentumScrollBegin={(e: NativeSyntheticEvent) => {
this.onMomentumScrollBegin(e);
}}
>
{this.renderList(this.columnValue)}
);
}
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.realIndex,
this.getActiveValue(),
this.props.columnIndex
);
}
}, 300);
}
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.realIndex,
this.getActiveValue(),
this.props.columnIndex
);
}
}, 300);
}
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!);
}
private caculateScrollIndex (e: NativeSyntheticEvent) {
let pIndex = Math.round(
e.nativeEvent.contentOffset.y / 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) {
/// index is realIndex
this.realIndex = index;
this.oldIndex = this.selectIndex;
this.selectIndex = this.checkValidIndex(index, this.props) + 2;
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 - 2];
return item;
}
private initColumnValue (column: any[]) {
this.columnValue = [];
this.columnValue.push(...column);
this.columnValue.unshift({}, {});
this.columnValue.push({}, {});
}
}
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,
},
});