From 0fa8c5be100f6e1cc139fbaf1849ad249cc6e304 Mon Sep 17 00:00:00 2001 From: iosLongFeng <646907689@qq.com> Date: Thu, 3 Dec 2020 16:57:25 +0800 Subject: [PATCH 1/2] Update index.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改scrollpicker快速拖动的问题 --- src/components/Scrollpicker/index.tsx | 545 +++++++++++--------------- 1 file changed, 229 insertions(+), 316 deletions(-) diff --git a/src/components/Scrollpicker/index.tsx b/src/components/Scrollpicker/index.tsx index 650f778..359ad0b 100644 --- a/src/components/Scrollpicker/index.tsx +++ b/src/components/Scrollpicker/index.tsx @@ -1,403 +1,316 @@ -import React from 'react' -import { View, Text, ScrollView, PixelRatio, ViewStyle } from 'react-native' -import variables from '../../common/styles/variables' -import { range } from '../../common/utils' -import scrollpickerStyles from './styles' - -export { scrollpickerStyles } - -const px = 1 / PixelRatio.get() -const DEFAULT_CONTAINER_HEIGHT = 1 - -interface ListItem { - label: string | number - [propName: string]: any -} - -export interface ScrollpickerProps { - style?: ViewStyle - list?: Array> | any - value?: number[] - proportion?: number[] - offsetCount?: number - onChange?: Function - renderItem?: Function -} - -interface ScrollpickerState { - list: Array> - value: number[] - proportion: number[] - targetItemHeight: number - containerHeight: number -} - -export class Scrollpicker extends React.Component { - containerRef = null - scrollers = [] - targetItemHeight = null - containerHeight = null - - static defaultProps = { - style: {}, - list: [ - ['第一列第一项', '第一列第二项', '第一列第三项'], - ['第二列第一项', '第二列第二项', '第二列第三项'], - ['第三列第一项', '第三列第二项', '第三列第三项'] - ], - value: [], - proportion: [2, 1, 1], - offsetCount: 2, - onChange: null, - renderItem: null - } - - constructor (props) { - super(props) - this.containerRef = null - - const data = this.initialize(props) - +import React from 'react'; +import {View, Text, ScrollView, PixelRatio} from 'react-native'; +import variables from '../../common/styles/variables'; +import {range} from '../../common/utils'; +import scrollpickerStyles from './styles'; + +export {scrollpickerStyles}; +const px = 1 / PixelRatio.get(); +const DEFAULT_CONTAINER_HEIGHT = 1; + +export class Scrollpicker extends React.Component { + constructor(props) { + super(props); + this.containerRef = null; + this.scrollers = []; + this.targetItemHeight = null; + this.containerHeight = null; + this.containerRef = null; + const data = this.initialize(props); this.state = { ...data, - targetItemHeight: null, - containerHeight: null - } - - this.scrollers = [] + containerHeight: null, + }; + this.scrollers = []; } - initialize (props) { - const data = this.initData(props) - - return data + initialize(props) { + const data = this.initData(props); + return data; } - initData (props) { - let { list, proportion, value } = props - + initData(props) { + let {list, proportion, value} = props; if (!list || !list.length) { - throw TypeError('提供有效的 list 参数') + throw TypeError('提供有效的 list 参数'); } - - const { offsetCount } = this.props - + const {offsetCount} = this.props; const placeholderList = range(offsetCount).map(() => { - return '' - }) - + return ''; + }); list = list.map(scrollItem => { - const tmp = scrollItem.concat() - - ;[].push.apply(tmp, placeholderList) - ;[].unshift.apply(tmp, placeholderList) - - return tmp - }) - - const length = list.length - - if ( - !proportion || + const tmp = scrollItem.concat(); + [].push.apply(tmp, placeholderList); + [].unshift.apply(tmp, placeholderList); + return tmp; + }); + const length = list.length; + if (!proportion || !proportion.length || - (proportion && proportion.length && proportion.length !== length) - ) { + (proportion && proportion.length && proportion.length !== length)) { proportion = range(length).map(() => { - return 1 - }) + return 1; + }); } - - if ( - !value || + if (!value || !value.length || - (value && value.length && value.length !== length) - ) { + (value && value.length && value.length !== length)) { value = range(length).map(() => { - return 0 - }) + return 0; + }); } - return { list, value, - proportion - } + proportion, + }; } - componentDidMount () { - this.getUIData(this.containerRef, DEFAULT_CONTAINER_HEIGHT).then((data: any) => { - const { targetItemHeight } = data - const containerHeight = this.resizeContainerHeight(targetItemHeight) - - this.setState( - { - containerHeight, - targetItemHeight - }, - () => { - this.getUIData(this.containerRef, this.state.containerHeight).then((uiData) => { - const { value } = this.state - - value.forEach((item, index) => { - this.scrollTo(index, item, false) - }) - }).catch((e) => { - console.log(e) - }) - } - ) + componentDidMount() { + this.getUIData(this.containerRef, DEFAULT_CONTAINER_HEIGHT).then((data) => { + const {targetItemHeight} = data; + const containerHeight = this.resizeContainerHeight(targetItemHeight); + this.setState({ + containerHeight, + targetItemHeight, + }, () => { + this.getUIData(this.containerRef, this.state.containerHeight).then((uiData) => { + const {value} = this.state; + value.forEach((item, index) => { + this.scrollTo(index, item, false); + }); + }).catch((e) => { + console.log(e); + }); + }); }).catch((e) => { - console.log(e) - }) + console.log(e); + }); + } + componentWillUnmount() { + this.timer && clearTimeout(this.timer) } - componentWillReceiveProps (nextProps) { - + componentWillReceiveProps(nextProps) { if (nextProps !== this.props) { - const data = this.initialize(nextProps) - - this.setState( - { - ...data - }, - () => { - setTimeout(() => { - const { value } = this.state - - value.forEach((item, index) => { - this.scrollTo(index, item) - }) - }) - } - ) + const data = this.initialize(nextProps); + this.setState({ + ...data, + }, () => { + setTimeout(() => { + const {value} = this.state; + value.forEach((item, index) => { + this.scrollTo(index, item); + }); + }); + }); } } - getUIData (element, accurateHeight, maxCount?) { - let count = 0 - maxCount = maxCount == null ? 20 : maxCount - + getUIData(element, accurateHeight, maxCount) { + let count = 0; + maxCount = maxCount == null ? 20 : maxCount; return new Promise((resolve, reject) => { - let toCheck = null + let toCheck = null; let measure = () => { - let ret = null - + let ret = null; element.measure((x, y, width, height, left, top) => { // console.log( // `Get container height: ${height}, accurate height: ${accurateHeight} and target item height: ${ // this.targetItemHeight // } for ${++count}th.` // ) - if (height) { // 安卓机器获取高度不精确 - const needToReset = height % 1 === 0 ? false : true - let minHeight - let maxHeight - + const needToReset = height % 1 === 0 ? false : true; + let minHeight; + let maxHeight; if (needToReset) { - minHeight = Math.floor(height) - maxHeight = minHeight + 1 + minHeight = Math.floor(height); + maxHeight = minHeight + 1; } else { - minHeight = maxHeight = height + minHeight = maxHeight = height; } - - if ( - (minHeight === accurateHeight || maxHeight === accurateHeight) && - this.targetItemHeight - ) { + if ((minHeight === accurateHeight || maxHeight === accurateHeight) && + this.targetItemHeight) { ret = { rect: { x, y, width, - height + height, }, - targetItemHeight: this.targetItemHeight - } + targetItemHeight: this.targetItemHeight, + }; } } - - toCheck(ret) - }) - } - + toCheck(ret); + }); + }; toCheck = (ret) => { if (ret) { - return resolve(ret) + return resolve(ret); } else { if (count < maxCount) { setTimeout(() => { - measure() - }, 20) + measure(); + }, 20); } else { - return reject('获取元素高度失败!') + return reject('获取元素高度失败!'); } } - } - - measure() - }) + }; + measure(); + }); } - resizeContainerHeight (targetItemHeight) { - const { offsetCount } = this.props - const ret = targetItemHeight + 2 * (targetItemHeight * offsetCount) - return ret + resizeContainerHeight(targetItemHeight) { + const {offsetCount} = this.props; + const ret = targetItemHeight + 2 * (targetItemHeight * offsetCount); + return ret; } - locateIndicator (targetItemHeight) { - const styles = scrollpickerStyles - const { offsetCount } = this.props - - return ( - - - - - - ) + locateIndicator(targetItemHeight) { + const styles = scrollpickerStyles; + const {offsetCount} = this.props; + return (React.createElement(View, {style: [styles.indicator], pointerEvents: 'none'}, + React.createElement(View, { + style: [ + styles.indicator, + styles.indicatorMask, + {bottom: targetItemHeight + offsetCount * targetItemHeight}, + {borderBottomWidth: 1 * px, borderBottomColor: variables.mtdBorderColorDark}, + ], + }), + React.createElement(View, { + style: [ + styles.indicator, + styles.indicatorMask, + {top: targetItemHeight + offsetCount * targetItemHeight}, + {borderTopWidth: 1 * px, borderTopColor: variables.mtdBorderColorDark}, + ], + }))); } - scrollTo (scrollIndex, targetItemIndex, animated?) { - const { targetItemHeight } = this.state + scrollTo(scrollIndex, targetItemIndex, animated) { + const {targetItemHeight} = this.state; // const { offsetCount } = this.props - this.scrollProper(scrollIndex, targetItemHeight * targetItemIndex, animated) - } + this.scrollProper(scrollIndex, targetItemHeight * targetItemIndex, animated); - onScroll (scrollIndex, scrollHeight) { - const targetItemIndex = this.scrollProper(scrollIndex, scrollHeight) - this.props.onChange && this.props.onChange(scrollIndex, targetItemIndex) } - scrollProper (scrollIndex, scrollHeight, animated?) { - const { targetItemHeight, list } = this.state - const { offsetCount } = this.props - const scrollListLength = list[scrollIndex].length + onScroll(scrollIndex, scrollHeight) { + this.timer && clearTimeout(this.timer); + this.timer = setTimeout(()=>{ + const targetItemIndex = this.scrollProper(scrollIndex, scrollHeight); + this.props.onChange && this.props.onChange(scrollIndex, targetItemIndex); - let newScrollHeight + },100) - const min = 0 - const max = (scrollListLength - 2 * offsetCount - 1) * targetItemHeight + } + scrollProper(scrollIndex, scrollHeight, animated) { + const {targetItemHeight, list} = this.state; + const {offsetCount} = this.props; + const scrollListLength = list[scrollIndex].length; + let newScrollHeight; + const min = 0; + const max = (scrollListLength - 2 * offsetCount - 1) * targetItemHeight; if (scrollHeight <= min) { - newScrollHeight = min + newScrollHeight = min; } else if (scrollHeight >= max) { - newScrollHeight = max + newScrollHeight = max; } else { - const quotient = parseInt(String(scrollHeight / targetItemHeight), 10) - newScrollHeight = quotient * targetItemHeight - - const halfHeight = targetItemHeight / 2 - + const quotient = parseInt(String(scrollHeight / targetItemHeight), 10); + newScrollHeight = quotient * targetItemHeight; + const halfHeight = targetItemHeight / 2; if (scrollHeight - newScrollHeight > halfHeight) { - newScrollHeight += targetItemHeight + newScrollHeight += targetItemHeight; } } - this.scrollers[scrollIndex] && this.scrollers[scrollIndex].scrollTo && this.scrollers[scrollIndex].scrollTo({ x: 0, y: newScrollHeight, - animated: animated === false ? false : true - }) - - const targetItemIndex = newScrollHeight / targetItemHeight - return targetItemIndex + animated: animated === false ? false : true, + }); + const targetItemIndex = newScrollHeight / targetItemHeight; + return targetItemIndex; } - render () { - const styles = scrollpickerStyles - const { list, proportion, containerHeight, targetItemHeight } = this.state - - return ( - { - this.containerRef = el - }} - style={[ + render() { + const styles = scrollpickerStyles; + const {list, proportion, containerHeight, targetItemHeight} = this.state; + return (React.createElement(View, { + ref: el => { + this.containerRef = el; + }, style: [ styles.container, this.props.style, - { height: containerHeight || DEFAULT_CONTAINER_HEIGHT } - ]} - > - {containerHeight && this.locateIndicator(targetItemHeight)} - - {list.map((scrollItem, scrollIndex) => { - return ( - - { - this.scrollers[scrollIndex] = c - }} - style={styles.scroller} - showsVerticalScrollIndicator={false} - contentContainerStyle={[styles.scrollerContentContainer]} - onScrollEndDrag={(e) => { - this.onScroll(scrollIndex, (e as any).nativeEvent.contentOffset.y) - }} - > - {scrollItem.map((item, index) => { - return ( - { - if ( - item && - this.targetItemHeight == null && - e.nativeEvent.layout.height - ) { - this.targetItemHeight = Math.ceil( - e.nativeEvent.layout.height - ) - // console.log( - // 'OnLayout get target item height:', - // this.targetItemHeight - // ) - } - }} - > - { - this.props.renderItem ? this.props.renderItem(item, index) : - - {typeof item === 'object' ? item.label : item} - - } - - ) - })} - - - ) - })} - - ) + {height: containerHeight || DEFAULT_CONTAINER_HEIGHT}, + ], + }, + containerHeight && this.locateIndicator(targetItemHeight), + list.map((scrollItem, scrollIndex) => { + return (React.createElement(View, { + key: scrollIndex, style: [ + styles.proportionWrapper, + {flex: Number(proportion[scrollIndex])}, + ], + }, + React.createElement(ScrollView, { + ref: c => { + this.scrollers[scrollIndex] = c; + }, + style: styles.scroller, + showsVerticalScrollIndicator: false, + contentContainerStyle: [styles.scrollerContentContainer], + onScrollEndDrag: (e) => { + this.onScroll(scrollIndex, e.nativeEvent.contentOffset.y); + }, + onMomentumScrollBegin:()=>{ + this.timer && clearTimeout(this.timer); + this.timer = null + }, + onMomentumScrollEnd: (e) => { + this.onScroll(scrollIndex, e.nativeEvent.contentOffset.y); + }, + }, scrollItem.map((item, index) => { + return (React.createElement(View, { + key: index, style: [styles.targetItem, {height: targetItemHeight}], onLayout: e => { + if (item && + this.targetItemHeight == null && + e.nativeEvent.layout.height) { + this.targetItemHeight = Math.ceil(e.nativeEvent.layout.height); + // console.log( + // 'OnLayout get target item height:', + // this.targetItemHeight + // ) + } + }, + }, this.props.renderItem ? this.props.renderItem(item, index) : + React.createElement(Text, { + style: [ + styles.targetItemContent, + ], numberOfLines: 1, + }, typeof item === 'object' ? item.label : item))); + })))); + }))); } } + +Scrollpicker.defaultProps = { + style: {}, + list: [ + ['第一列第一项', '第一列第二项', '第一列第三项'], + ['第二列第一项', '第二列第二项', '第二列第三项'], + ['第三列第一项', '第三列第二项', '第三列第三项'], + ], + value: [], + proportion: [2, 1, 1], + offsetCount: 2, + onChange: null, + renderItem: null, +}; +//# sourceMappingURL=index.js.map From 574323d6c657a198bd9303b17f0ebf0cfc3cf395 Mon Sep 17 00:00:00 2001 From: iosLongFeng <646907689@qq.com> Date: Thu, 3 Dec 2020 17:15:40 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=BB=91=E5=8A=A8?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改滑动的问题 --- src/components/Scrollpicker/index.tsx | 545 +++++++++++++++----------- 1 file changed, 323 insertions(+), 222 deletions(-) diff --git a/src/components/Scrollpicker/index.tsx b/src/components/Scrollpicker/index.tsx index 359ad0b..e39807f 100644 --- a/src/components/Scrollpicker/index.tsx +++ b/src/components/Scrollpicker/index.tsx @@ -1,316 +1,417 @@ -import React from 'react'; -import {View, Text, ScrollView, PixelRatio} from 'react-native'; -import variables from '../../common/styles/variables'; -import {range} from '../../common/utils'; -import scrollpickerStyles from './styles'; - -export {scrollpickerStyles}; -const px = 1 / PixelRatio.get(); -const DEFAULT_CONTAINER_HEIGHT = 1; - -export class Scrollpicker extends React.Component { - constructor(props) { - super(props); - this.containerRef = null; - this.scrollers = []; - this.targetItemHeight = null; - this.containerHeight = null; - this.containerRef = null; - const data = this.initialize(props); +import React from 'react' +import { View, Text, ScrollView, PixelRatio, ViewStyle } from 'react-native' +import variables from '../../common/styles/variables' +import { range } from '../../common/utils' +import scrollpickerStyles from './styles' + +export { scrollpickerStyles } + +const px = 1 / PixelRatio.get() +const DEFAULT_CONTAINER_HEIGHT = 1 + +interface ListItem { + label: string | number + [propName: string]: any +} + +export interface ScrollpickerProps { + style?: ViewStyle + list?: Array> | any + value?: number[] + proportion?: number[] + offsetCount?: number + onChange?: Function + renderItem?: Function +} + +interface ScrollpickerState { + list: Array> + value: number[] + proportion: number[] + targetItemHeight: number + containerHeight: number +} + +export class Scrollpicker extends React.Component { + containerRef = null + scrollers = [] + targetItemHeight = null + containerHeight = null + + static defaultProps = { + style: {}, + list: [ + ['第一列第一项', '第一列第二项', '第一列第三项'], + ['第二列第一项', '第二列第二项', '第二列第三项'], + ['第三列第一项', '第三列第二项', '第三列第三项'] + ], + value: [], + proportion: [2, 1, 1], + offsetCount: 2, + onChange: null, + renderItem: null + } + + constructor (props) { + super(props) + this.containerRef = null + + const data = this.initialize(props) + this.state = { ...data, + targetItemHeight: null, - containerHeight: null, - }; - this.scrollers = []; + containerHeight: null + } + + this.scrollers = [] } - initialize(props) { - const data = this.initData(props); - return data; + initialize (props) { + const data = this.initData(props) + + return data } - initData(props) { - let {list, proportion, value} = props; + initData (props) { + let { list, proportion, value } = props + if (!list || !list.length) { - throw TypeError('提供有效的 list 参数'); + throw TypeError('提供有效的 list 参数') } - const {offsetCount} = this.props; + + const { offsetCount } = this.props + const placeholderList = range(offsetCount).map(() => { - return ''; - }); + return '' + }) + list = list.map(scrollItem => { - const tmp = scrollItem.concat(); - [].push.apply(tmp, placeholderList); - [].unshift.apply(tmp, placeholderList); - return tmp; - }); - const length = list.length; - if (!proportion || + const tmp = scrollItem.concat() + + ;[].push.apply(tmp, placeholderList) + ;[].unshift.apply(tmp, placeholderList) + + return tmp + }) + + const length = list.length + + if ( + !proportion || !proportion.length || - (proportion && proportion.length && proportion.length !== length)) { + (proportion && proportion.length && proportion.length !== length) + ) { proportion = range(length).map(() => { - return 1; - }); + return 1 + }) } - if (!value || + + if ( + !value || !value.length || - (value && value.length && value.length !== length)) { + (value && value.length && value.length !== length) + ) { value = range(length).map(() => { - return 0; - }); + return 0 + }) } + return { list, value, - proportion, - }; + proportion + } } - componentDidMount() { - this.getUIData(this.containerRef, DEFAULT_CONTAINER_HEIGHT).then((data) => { - const {targetItemHeight} = data; - const containerHeight = this.resizeContainerHeight(targetItemHeight); - this.setState({ - containerHeight, - targetItemHeight, - }, () => { - this.getUIData(this.containerRef, this.state.containerHeight).then((uiData) => { - const {value} = this.state; - value.forEach((item, index) => { - this.scrollTo(index, item, false); - }); - }).catch((e) => { - console.log(e); - }); - }); + componentDidMount () { + this.getUIData(this.containerRef, DEFAULT_CONTAINER_HEIGHT).then((data: any) => { + const { targetItemHeight } = data + const containerHeight = this.resizeContainerHeight(targetItemHeight) + + this.setState( + { + containerHeight, + targetItemHeight + }, + () => { + this.getUIData(this.containerRef, this.state.containerHeight).then((uiData) => { + const { value } = this.state + + value.forEach((item, index) => { + this.scrollTo(index, item, false) + }) + }).catch((e) => { + console.log(e) + }) + } + ) }).catch((e) => { - console.log(e); - }); + console.log(e) + }) } + componentWillUnmount() { this.timer && clearTimeout(this.timer) } - componentWillReceiveProps(nextProps) { + componentWillReceiveProps (nextProps) { + if (nextProps !== this.props) { - const data = this.initialize(nextProps); - this.setState({ - ...data, - }, () => { - setTimeout(() => { - const {value} = this.state; - value.forEach((item, index) => { - this.scrollTo(index, item); - }); - }); - }); + const data = this.initialize(nextProps) + + this.setState( + { + ...data + }, + () => { + setTimeout(() => { + const { value } = this.state + + value.forEach((item, index) => { + this.scrollTo(index, item) + }) + }) + } + ) } } - getUIData(element, accurateHeight, maxCount) { - let count = 0; - maxCount = maxCount == null ? 20 : maxCount; + getUIData (element, accurateHeight, maxCount?) { + let count = 0 + maxCount = maxCount == null ? 20 : maxCount + return new Promise((resolve, reject) => { - let toCheck = null; + let toCheck = null let measure = () => { - let ret = null; + let ret = null + element.measure((x, y, width, height, left, top) => { // console.log( // `Get container height: ${height}, accurate height: ${accurateHeight} and target item height: ${ // this.targetItemHeight // } for ${++count}th.` // ) + if (height) { // 安卓机器获取高度不精确 - const needToReset = height % 1 === 0 ? false : true; - let minHeight; - let maxHeight; + const needToReset = height % 1 === 0 ? false : true + let minHeight + let maxHeight + if (needToReset) { - minHeight = Math.floor(height); - maxHeight = minHeight + 1; + minHeight = Math.floor(height) + maxHeight = minHeight + 1 } else { - minHeight = maxHeight = height; + minHeight = maxHeight = height } - if ((minHeight === accurateHeight || maxHeight === accurateHeight) && - this.targetItemHeight) { + + if ( + (minHeight === accurateHeight || maxHeight === accurateHeight) && + this.targetItemHeight + ) { ret = { rect: { x, y, width, - height, + height }, - targetItemHeight: this.targetItemHeight, - }; + targetItemHeight: this.targetItemHeight + } } } - toCheck(ret); - }); - }; + + toCheck(ret) + }) + } + toCheck = (ret) => { if (ret) { - return resolve(ret); + return resolve(ret) } else { if (count < maxCount) { setTimeout(() => { - measure(); - }, 20); + measure() + }, 20) } else { - return reject('获取元素高度失败!'); + return reject('获取元素高度失败!') } } - }; - measure(); - }); - } + } - resizeContainerHeight(targetItemHeight) { - const {offsetCount} = this.props; - const ret = targetItemHeight + 2 * (targetItemHeight * offsetCount); - return ret; + measure() + }) } - locateIndicator(targetItemHeight) { - const styles = scrollpickerStyles; - const {offsetCount} = this.props; - return (React.createElement(View, {style: [styles.indicator], pointerEvents: 'none'}, - React.createElement(View, { - style: [ - styles.indicator, - styles.indicatorMask, - {bottom: targetItemHeight + offsetCount * targetItemHeight}, - {borderBottomWidth: 1 * px, borderBottomColor: variables.mtdBorderColorDark}, - ], - }), - React.createElement(View, { - style: [ - styles.indicator, - styles.indicatorMask, - {top: targetItemHeight + offsetCount * targetItemHeight}, - {borderTopWidth: 1 * px, borderTopColor: variables.mtdBorderColorDark}, - ], - }))); + resizeContainerHeight (targetItemHeight) { + const { offsetCount } = this.props + const ret = targetItemHeight + 2 * (targetItemHeight * offsetCount) + return ret } - scrollTo(scrollIndex, targetItemIndex, animated) { - const {targetItemHeight} = this.state; - // const { offsetCount } = this.props - this.scrollProper(scrollIndex, targetItemHeight * targetItemIndex, animated); + locateIndicator (targetItemHeight) { + const styles = scrollpickerStyles + const { offsetCount } = this.props + return ( + + + + + ) } - onScroll(scrollIndex, scrollHeight) { + scrollTo (scrollIndex, targetItemIndex, animated?) { + const { targetItemHeight } = this.state + // const { offsetCount } = this.props + this.scrollProper(scrollIndex, targetItemHeight * targetItemIndex, animated) + } + + onScroll (scrollIndex, scrollHeight) { this.timer && clearTimeout(this.timer); this.timer = setTimeout(()=>{ const targetItemIndex = this.scrollProper(scrollIndex, scrollHeight); this.props.onChange && this.props.onChange(scrollIndex, targetItemIndex); },100) - } - scrollProper(scrollIndex, scrollHeight, animated) { - const {targetItemHeight, list} = this.state; - const {offsetCount} = this.props; - const scrollListLength = list[scrollIndex].length; - let newScrollHeight; - const min = 0; - const max = (scrollListLength - 2 * offsetCount - 1) * targetItemHeight; + scrollProper (scrollIndex, scrollHeight, animated?) { + const { targetItemHeight, list } = this.state + const { offsetCount } = this.props + const scrollListLength = list[scrollIndex].length + + let newScrollHeight + + const min = 0 + const max = (scrollListLength - 2 * offsetCount - 1) * targetItemHeight + if (scrollHeight <= min) { - newScrollHeight = min; + newScrollHeight = min } else if (scrollHeight >= max) { - newScrollHeight = max; + newScrollHeight = max } else { - const quotient = parseInt(String(scrollHeight / targetItemHeight), 10); - newScrollHeight = quotient * targetItemHeight; - const halfHeight = targetItemHeight / 2; + const quotient = parseInt(String(scrollHeight / targetItemHeight), 10) + newScrollHeight = quotient * targetItemHeight + + const halfHeight = targetItemHeight / 2 + if (scrollHeight - newScrollHeight > halfHeight) { - newScrollHeight += targetItemHeight; + newScrollHeight += targetItemHeight } } + this.scrollers[scrollIndex] && this.scrollers[scrollIndex].scrollTo && this.scrollers[scrollIndex].scrollTo({ x: 0, y: newScrollHeight, - animated: animated === false ? false : true, - }); - const targetItemIndex = newScrollHeight / targetItemHeight; - return targetItemIndex; + animated: animated === false ? false : true + }) + + const targetItemIndex = newScrollHeight / targetItemHeight + return targetItemIndex } - render() { - const styles = scrollpickerStyles; - const {list, proportion, containerHeight, targetItemHeight} = this.state; - return (React.createElement(View, { - ref: el => { - this.containerRef = el; - }, style: [ + render () { + const styles = scrollpickerStyles + const { list, proportion, containerHeight, targetItemHeight } = this.state + + return ( + { + this.containerRef = el + }} + style={[ styles.container, this.props.style, - {height: containerHeight || DEFAULT_CONTAINER_HEIGHT}, - ], - }, - containerHeight && this.locateIndicator(targetItemHeight), - list.map((scrollItem, scrollIndex) => { - return (React.createElement(View, { - key: scrollIndex, style: [ - styles.proportionWrapper, - {flex: Number(proportion[scrollIndex])}, - ], - }, - React.createElement(ScrollView, { - ref: c => { - this.scrollers[scrollIndex] = c; - }, - style: styles.scroller, - showsVerticalScrollIndicator: false, - contentContainerStyle: [styles.scrollerContentContainer], - onScrollEndDrag: (e) => { - this.onScroll(scrollIndex, e.nativeEvent.contentOffset.y); - }, - onMomentumScrollBegin:()=>{ - this.timer && clearTimeout(this.timer); - this.timer = null - }, - onMomentumScrollEnd: (e) => { - this.onScroll(scrollIndex, e.nativeEvent.contentOffset.y); - }, - }, scrollItem.map((item, index) => { - return (React.createElement(View, { - key: index, style: [styles.targetItem, {height: targetItemHeight}], onLayout: e => { - if (item && - this.targetItemHeight == null && - e.nativeEvent.layout.height) { - this.targetItemHeight = Math.ceil(e.nativeEvent.layout.height); - // console.log( - // 'OnLayout get target item height:', - // this.targetItemHeight - // ) + { height: containerHeight || DEFAULT_CONTAINER_HEIGHT } + ]} + > + {containerHeight && this.locateIndicator(targetItemHeight)} + + {list.map((scrollItem, scrollIndex) => { + return ( + + { + this.scrollers[scrollIndex] = c + }} + style={styles.scroller} + showsVerticalScrollIndicator={false} + contentContainerStyle={[styles.scrollerContentContainer]} + onScrollEndDrag: (e) => { + this.onScroll(scrollIndex, e.nativeEvent.contentOffset.y); + }, + onMomentumScrollBegin:()=>{ + this.timer && clearTimeout(this.timer); + this.timer = null + }, + onMomentumScrollEnd: (e) => { + this.onScroll(scrollIndex, e.nativeEvent.contentOffset.y); } - }, - }, this.props.renderItem ? this.props.renderItem(item, index) : - React.createElement(Text, { - style: [ - styles.targetItemContent, - ], numberOfLines: 1, - }, typeof item === 'object' ? item.label : item))); - })))); - }))); + > + {scrollItem.map((item, index) => { + return ( + { + if ( + item && + this.targetItemHeight == null && + e.nativeEvent.layout.height + ) { + this.targetItemHeight = Math.ceil( + e.nativeEvent.layout.height + ) + // console.log( + // 'OnLayout get target item height:', + // this.targetItemHeight + // ) + } + }} + > + { + this.props.renderItem ? this.props.renderItem(item, index) : + + {typeof item === 'object' ? item.label : item} + + } + + ) + })} + + + ) + })} + + ) } } - -Scrollpicker.defaultProps = { - style: {}, - list: [ - ['第一列第一项', '第一列第二项', '第一列第三项'], - ['第二列第一项', '第二列第二项', '第二列第三项'], - ['第三列第一项', '第三列第二项', '第三列第三项'], - ], - value: [], - proportion: [2, 1, 1], - offsetCount: 2, - onChange: null, - renderItem: null, -}; -//# sourceMappingURL=index.js.map