Skip to content

Instantly share code, notes, and snippets.

@machadogj
Created March 17, 2016 20:18
Show Gist options
  • Save machadogj/392e0314f51100a0541d to your computer and use it in GitHub Desktop.
Save machadogj/392e0314f51100a0541d to your computer and use it in GitHub Desktop.
React native simple picker
"use strict";
import React from "react-native";
let {
StyleSheet,
View,
ScrollView,
PropTypes,
Component,
Text
} = React;
import styles from "./styles";
const pickerHeight = 48;
const valueHeight = 40;
const sneak = 2;
const gap = (pickerHeight - (2 * sneak) - valueHeight) / 2;
export default class Picker extends Component {
displayName = "picker";
static propTypes = {
initialValue: PropTypes.string,
onValueChange: PropTypes.func,
values: PropTypes.array.isRequired
};
static defaultProps = {
};
state = {
activeValue: this.props.initialValue
};
componentDidMount() {
if (this.props.initialValue) {
console.log("initialValue", this.props.initialValue); //eslint-disable-line
let index = this.props.values.indexOf(this.props.initialValue);
console.log("index", index); //eslint-disable-line
this.goToPage(index);
}
}
goToPage(position) {
if (position + 1 > this.props.values.length) {
position--;
}
// let { valueHeight } = this.props;
// let { gap } = this.state;
let pagePosition = position * (valueHeight + gap);
console.log("going to page ", position, { //eslint-disable-line
valueHeight,
gap,
pagePosition
});
this.scrollView.scrollTo(pagePosition, 0);
if (this.props.onValueChange) {
this.props.onValueChange(this.props.values[position]);
}
}
handleScrollEnd = (e) => {
let pageOffset = valueHeight + gap;
//select page based on the position of the middle of the screen.
let currentPosition = e.nativeEvent.contentOffset.y + (pickerHeight / 2);
let currentValueIndex = ~~(currentPosition / pageOffset);
console.log("handleScrollEnd", { //eslint-disable-line
state: this.state,
valueHeight,
gap,
pageOffset,
currentPosition,
currentValueIndex,
x: e.nativeEvent.contentOffset.x,
y: e.nativeEvent.contentOffset.y
});
this.scrollView.scrollTo(currentValueIndex * pageOffset, 0);
this.goToPage(currentValueIndex);
};
render() {
let { values } = this.props;
let valuesContainerHeight = values.length * (valueHeight + gap); //+ this.state.pickerHeight
let computedStyles = StyleSheet.create({
valuesContainer: {
paddingTop: sneak + gap / 2,
paddingBottom: sneak + gap / 2,
justifyContent: "flex-start",
height: valuesContainerHeight
},
value: {
height: valueHeight,
justifyContent: "center",
marginTop: gap / 2,
marginBottom: gap / 2
}
});
let valuesComponents = values.map((v) => {
return (
<View
key={ v }
style={ [ computedStyles.value ] }
>
<Text style={ [ styles.valueText ] }>{ v }</Text>
</View>
);
});
return (
<View style={ [ { flex: 1 } ] }>
<ScrollView
automaticallyAdjustContentInsets={ false }
bounces
decelerationRate={ 0.9998 }
horizontal={ false }
onScrollEndDrag={ this.handleScrollEnd }
ref={ c => this.scrollView = c }
showsVerticalScrollIndicator={ false }
style={ {height: pickerHeight} }
>
<View style={ [ computedStyles.valuesContainer ] }>
{ valuesComponents }
</View>
</ScrollView>
</View>
);
}
}
import { StyleSheet } from "react-native";
let styles = StyleSheet.create({
container: {
// flex: 1,
// justifyContent: "center"
},
value: {
// flex: 1
},
valueText: {
fontSize: 32
}
});
export default styles;
//...
<Picker
initialValue={ "02" }
onValueChange={ this._handleHoursChanged.bind(this) }
values={ [ "01", "02", "03", "04", "05", "06", "07", "08" ] }
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment