diff --git a/README.md b/README.md
index 31a593c689db94f710a6c7e6c60a7b088e6606be..dc9c1465325a362492a2b9645bff68bfed74af3e 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,9 @@ Needs react-native >= 0.14.2
- selectedValue any
- onPickerDone function
+####Methods
+- toggle show or hide picker, default to be hiden
+
###Usage
####Step 1 - install
@@ -38,4 +41,66 @@ Needs react-native >= 0.14.2
selectedValue={}//default to be selected value
onPickerDone={}//when confirm your choice
/>
-```
\ No newline at end of file
+```
+
+###Notice
+
+####support two modes:
+
+1. parallel: such as time picker, wheels have no connection with each other
+
+2. cascade: such as date picker, address picker .etc, when front wheel changed, the behind wheels will all be reset
+
+####parallel:
+
+- single wheel:
+
+```javascript
+ pickerData = [1,2,3,4];
+ selectedValue = 3;
+```
+
+- two or more wheel:
+
+```javascript
+ pickerData = [
+ [1,2,3,4],
+ [5,6,7,8],
+ ...
+ ];
+ selectedValue = [1, 5];
+```
+
+####cascade:
+
+- two wheel
+
+```javascript
+ pickerData = {
+ {
+ a: [1,2,3,4],
+ b: [5,6,7,8],
+ ...
+ }
+ };
+ selectedValue = ['a', 2];
+```
+
+- three wheel
+
+```javascript
+ pickerData = {
+ a: {
+ a1: [1,2,3,4],
+ a2: [5,6,7,8],
+ a3: [9,10,11,12]
+ },
+ b: {
+ b1: [1,2,3,4],
+ b2: [5,6,7,8],
+ b3: [9,10,12,12]
+ }
+ ...
+ };
+ selectedValue = ['a', 'a1', 1];
+```
diff --git a/index.js b/index.js
index 66300663d41bb0bf44ed02fe64ca1f5e7ea0800f..0b8b05ee605437cd9a81e466ea1744d1560531df 100644
--- a/index.js
+++ b/index.js
@@ -14,31 +14,78 @@ import React, {
import PickerAndroid from 'react-native-picker-android';
let Picker = Platform.OS === 'ios' ? PickerIOS : PickerAndroid;
-let PickerItem = Picker.Item;
+let PickerItem = Picker.item;
let width = Dimensions.get('window').width;
let height = Dimensions.get('window').height;
export default class PickerAny extends React.Component {
static propTypes = {
+ pickerBtnText: PropTypes.string,
+ pickerBtnStyle: PropTypes.any,
+ pickerToolBarStyle: PropTypes.any,
+ pickerItemStyle: PropTypes.any,
pickerHeight: PropTypes.number,
showDuration: PropTypes.number,
- pickerData: PropTypes.array,
+ pickerData: PropTypes.any.isRequired,
+ selectedValue: PropTypes.any.isRequired,
onPickerDone: PropTypes.func
}
static defaultProps = {
- pickerHeight: height/3,
+ pickerBtnText: '完成',
+ pickerHeight: 250,
showDuration: 300,
onPickerDone: ()=>{}
}
constructor(props, context){
super(props, context);
+ //the pickedValue must looks like [wheelone's, wheeltwo's, ...]
+ //this.state.selectedValue may be the result of the first pickerWheel
+ let pickedValue = this.props.selectedValue;
+ let pickerData = this.props.pickerData;
+ let pickerStyle = pickerData.constructor === Array ? 'parallel' : 'cascade';
+ let firstWheelData;
+ let firstPickedData;
+ let secondWheelData;
+ let secondPickedDataIndex;
+ let thirdWheelData;
+ let thirdPickedDataIndex;
+ let cascadeData = {};
+ if(pickerStyle === 'parallel'){
+ //compatible single wheel sence
+ if(pickedValue.constructor !== Array){
+ pickedValue = [pickedValue];
+ }
+ if(pickerData[0].constructor !== Array){
+ pickerData = [pickerData];
+ }
+ }
+ else if(pickerStyle === 'cascade'){
+ //only support three stage
+ firstWheelData = Object.keys(pickerData);
+ firstPickedData = this.props.selectedValue[0];
+ secondPickedData = this.props.selectedValue[1];
+ cascadeData = this._getCascadeData(pickerData, pickedValue, firstPickedData, secondPickedData, true);
+ }
this.state = {
- selectedValue: this.props.selectedValue,
- slideAnim: new Animated.Value(-this.props.pickerHeight)
+ slideAnim: new Animated.Value(-this.props.pickerHeight),
+ pickerData,
+ selectedValue: pickedValue,
+ //list of first wheel data
+ firstWheelData,
+ //first wheel selected value
+ firstPickedData,
+ //list of second wheel data and pickedDataIndex
+ secondWheelData: cascadeData.secondWheelData,
+ secondPickedDataIndex: cascadeData.secondPickedDataIndex,
+ //third wheel selected value and pickedDataIndex
+ thirdWheelData: cascadeData.thirdWheelData,
+ thirdPickedDataIndex: cascadeData.thirdPickedDataIndex
};
+ this.pickedValue = pickedValue;
+ this.pickerStyle = pickerStyle;
}
_slideUp(){
@@ -100,47 +147,257 @@ export default class PickerAny extends React.Component {
}
_pickerFinish(){
- let pickedValue = this.pickedValue === undefined ? this.state.selectedValue : this.pickedValue;
this._toggle();
- this.props.onPickerDone(pickedValue);
+ this.props.onPickerDone(this.pickedValue);
+ }
+
+ _renderParallelWheel(pickerData){
+ let me = this;
+ return pickerData.map((item, index) => {
+ return (
+
+ {
+ me.pickedValue.splice(index, 1, value);
+ me.setState({
+ selectedValue: me.pickedValue
+ });
+ }} >
+ {item.map((value, index) => (
+ )
+ )}
+
+
+ );
+ });
+ }
+
+ _getCascadeData(pickerData, pickedValue, firstPickedData, secondPickedData, onInit){
+ let secondWheelData;
+ let secondPickedDataIndex;
+ let thirdWheelData;
+ let thirdPickedDataIndex;
+ //only support two and three stage
+ for(let key in pickerData){
+ //two stage
+ if(pickerData[key].constructor === Array){
+ secondWheelData = pickerData[firstPickedData];
+ if(onInit){
+ secondWheelData.forEach(function(v, k){
+ if(v === pickedValue[1]){
+ secondPickedDataIndex = k;
+ }
+ }.bind(this));
+ }
+ else{
+ secondPickedDataIndex = 0;
+ }
+ break;
+ }
+ //three stage
+ else{
+ secondWheelData = Object.keys(pickerData[firstPickedData]);
+ if(onInit){
+ secondWheelData.forEach(function(v, k){
+ if(v === pickedValue[1]){
+ secondPickedDataIndex = k;
+ }
+ }.bind(this));
+ }
+ else{
+ secondPickedDataIndex = 0;
+ }
+ thirdWheelData = pickerData[firstPickedData][secondPickedData];
+ if(onInit){
+ thirdWheelData.forEach(function(v, k){
+ if(v === pickedValue[2]){
+ thirdPickedDataIndex = k;
+ }
+ })
+ }
+ else{
+ thirdPickedDataIndex = 0;
+ }
+ break;
+ }
+ }
+
+ return {
+ secondWheelData,
+ secondPickedDataIndex,
+ thirdWheelData,
+ thirdPickedDataIndex
+ }
+ }
+
+ _renderCascadeWheel(pickerData){
+ let me = this;
+ let thirdWheel = me.state.thirdWheelData && (
+
+ {
+ //on ios platform 'this' refers to Picker?
+ me.pickedValue.splice(2, 1, me.state.thirdWheelData[index]);
+ me.setState({
+ thirdPickedDataIndex: index
+ });
+ }} >
+ {me.state.thirdWheelData.map((value, index) => (
+ )
+ )}
+
+
+ );
+
+ return (
+
+
+ {
+ let secondWheelData = Object.keys(pickerData[value]);
+ cascadeData = me._getCascadeData(pickerData, me.pickedValue, value, secondWheelData[0]);
+ //when onPicked, this.pickedValue will pass to the parent
+ //when firstWheel changed, second and third will also change
+ if(cascadeData.thirdWheelData){
+ me.pickedValue.splice(0, 3, value, cascadeData.secondWheelData[0], cascadeData.thirdWheelData[0]);
+ }
+ else{
+ me.pickedValue.splice(0, 2, value, cascadeData.secondWheelData[0]);
+ }
+
+ me.setState({
+ selectedValue: value,
+ firstPickedData: value,
+ secondWheelData: cascadeData.secondWheelData,
+ secondPickedDataIndex: 0,
+ thirdWheelData: cascadeData.thirdWheelData,
+ thirdPickedDataIndex: 0
+ });
+ me.refs.secondWheel && me.refs.secondWheel.moveTo && me.refs.secondWheel.moveTo(0);
+ me.refs.thirdWheel && me.refs.thirdWheel.moveTo && me.refs.thirdWheel.moveTo(0);
+ }} >
+ {me.state.firstWheelData.map((value, index) => (
+ )
+ )}
+
+
+
+ {
+ let thirdWheelData = pickerData[me.state.firstPickedData][me.state.secondWheelData[index]];
+ if(thirdWheelData){
+ me.pickedValue.splice(1, 2, me.state.secondWheelData[index], thirdWheelData[0]);
+ }
+ else{
+ me.pickedValue.splice(1, 1, me.state.secondWheelData[index]);
+ }
+
+ me.setState({
+ secondPickedDataIndex: index,
+ thirdWheelData,
+ thirdPickedDataIndex: 0
+ });
+ me.refs.thirdWheel && me.refs.thirdWheel.moveTo && me.refs.thirdWheel.moveTo(0);
+ }} >
+ {me.state.secondWheelData.map((value, index) => (
+ )
+ )}
+
+
+ {thirdWheel}
+
+ );
+ }
+
+ _renderWheel(pickerData){
+ /*
+ some sences:
+ 1. single wheel:
+ [1,2,3,4]
+ 2. two or more:
+ [
+ [1,2,3,4],
+ [5,6,7,8],
+ ...
+ ]
+ 3. two stage cascade:
+ {
+ a: [1,2,3,4],
+ b: [5,6,7,8],
+ ...
+ }
+ 4. three stage cascade:
+ {
+ a: {
+ a1: [1,2,3,4],
+ a2: [5,6,7,8],
+ a3: [9,10,11,12]
+ },
+ b: {
+ b1: [1,2,3,4],
+ b2: [5,6,7,8],
+ b3: [9,10,12,12]
+ }
+ ...
+ }
+ we call 1、2 parallel and 3、4 cascade
+ */
+ let wheel = null;
+ if(this.pickerStyle === 'parallel'){
+ wheel = this._renderParallelWheel(pickerData);
+ }
+ else if(this.pickerStyle === 'cascade'){
+ wheel = this._renderCascadeWheel(pickerData);
+ }
+ return wheel;
}
render(){
- let pickerBtn = Platform.OS === 'ios' ? null : (
+ /*let pickerBtn = Platform.OS === 'ios' ? null : (
上一个
下一个
- );
+ );*/
+ let pickerBtn = null;
return (
-
+
{pickerBtn}
- 完成
+ {this.props.pickerBtnText}
- this.pickerWheel = pickerWheel }
- selectedValue={this.state.selectedValue}
- onValueChange={value => {
- this.pickedValue = value;
- this.setState({
- selectedValue: value
- });
- }} >
- {this.props.pickerData.map((value, index) => (
- )
- )}
-
+
+ {this._renderWheel(this.state.pickerData)}
+
);
}
@@ -148,13 +405,19 @@ export default class PickerAny extends React.Component {
let styles = StyleSheet.create({
picker: {
- flex: 1,
+ width: width,
position: 'absolute',
bottom: 0,
left: 0,
backgroundColor: '#bdc0c7',
+ overflow: 'hidden'
+ },
+ pickerWrap: {
width: width,
- overflow: 'hidden',
+ flexDirection: 'row'
+ },
+ pickerWheel: {
+ flex: 1
},
pickerToolbar: {
height: 30,
diff --git a/package.json b/package.json
index d4895fab932ea3a48827cf8bf06efe4c9f1b91bc..8316143941e578804c07f93fc74c16f2d79f9e7a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native-picker",
- "version": "0.1.2",
+ "version": "0.2.0",
"description": "react-native-picker",
"main": "index.js",
"scripts": {