react-native-arenakit
Version:
为编写arena app中react native应用提供基础的ui及原生能力api支撑
157 lines (122 loc) • 4.08 kB
JavaScript
/**
* Created by dingle on 2017/3/31.
*/
import React, {PureComponent}from 'react';
import {
View,
StyleSheet,
Text,
ScrollView,
InteractionManager,
Platform
} from 'react-native';
import PropTypes from 'prop-types';
class DLPicker extends PureComponent {
constructor(props) {
super(props);
this.state = {
scrollIndexF: this.props.selectedIndex
}
}
static propTypes = {
data: PropTypes.array,
itemHeight: PropTypes.number.isRequired,
onSelectedItem: PropTypes.func.isRequired,
selectedIndex: PropTypes.number
};
componentDidMount() {
this.scrollToIndex(this.props.selectedIndex);
}
scrollToIndex(selectedIndex) {
let contentOffsetY = (selectedIndex) * this.props.itemHeight;
InteractionManager.runAfterInteractions(() => {
//先判断scrollView创建好了没,再去滚动,防止点击太快导致的bug
this._scrollView&&this._scrollView.scrollTo({x: 0, y: contentOffsetY, animated: true});
});
}
render() {
let items = this.loadHolderViews();
items.push(this.props.data.map((data, index) => {
let dif = Math.abs(index - this.state.scrollIndexF);
let itemOpacity = 1 - dif * 0.2;
let scale = 1 - dif * 0.1;
return (
<View key={index} style={[styles.itemStyle, {height: this.props.itemHeight, opacity: itemOpacity}]}>
<Text style={[styles.itemLabelStyle, {transform: [{scale: scale}]}]}
allowFontScaling={false}>{data.label || data}</Text>
</View>
)
}));
items.push(this.loadHolderViews());
return (
<ScrollView ref={(scrollView) => {this._scrollView = scrollView}}
onScroll={this._onScroll.bind(this)}
scrollEventThrottle={50}
showsVerticalScrollIndicator={false}
snapToInterval={this.props.itemHeight}
snapToAlignment={'center'}
onMomentumScrollEnd={this._onMomentumScrollEnd.bind(this)}
onScrollEndDrag={this._onScrollEndDrag.bind(this)}
>
{items}
</ScrollView>
)
}
loadHolderViews() {
let views = [1, 2, 3].map((v, i) => {
return (
<View key={i} style={[styles.itemStyle, {height: this.props.itemHeight}]}/>
)
});
return views;
}
_onScroll(e) {
let contentOffsetY = e.nativeEvent.contentOffset.y;
// let scrollHeight = e.nativeEvent.layoutMeasurement.height;
let itemHeight = this.props.itemHeight;
let itemIndexF = contentOffsetY / itemHeight;
this.setState({
scrollIndexF: itemIndexF
});
}
_onMomentumScrollEnd(e) {
this.scrollEndTodo(e);
}
_onScrollEndDrag(e) {
if (Platform.OS == 'android') {
this.scrollEndTodo(e);
}
}
scrollEndTodo(e) {
let itemHeight = this.props.itemHeight;
let itemIndex = Math.round(e.nativeEvent.contentOffset.y / itemHeight);
if (Platform.OS == 'android') {
this._scrollView.scrollTo({x: 0, y: itemIndex * itemHeight, animated: true});
}
if (itemIndex < this.props.data.length) {
let itemData = this.props.data[itemIndex];
if(itemData&&itemData.value){
this.props.onSelectedItem(itemData);
}else {
if(__DEV__){
console.log('异常')
}
}
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
itemStyle: {
borderColor: '#000000',
justifyContent: 'center'
},
itemLabelStyle: {
fontSize: 20,
color: '#121212',
textAlign: 'center'
}
});
export default DLPicker