React Native之Picker组件详解

2018-02-06 10:39:31 浏览数 (1)

Picker简介

在iOS和Android中选择器(Picker)是常见的控件之一,比如TimePickr(Android),pickerView(ios),并且这些基本控件可以实现诸如地址选择等效果。在RN开发中,系统也为我们提供Picker控件。应用如下:

代码语言:javascript复制
<Picker
  selectedValue={this.state.language}
  onValueChange={(lang) => this.setState({language: lang})}>
  <Picker.Item label="Java" value="java" />
  <Picker.Item label="JavaScript" value="js" />
</Picker>

Picker属性

onValueChange 某一项被选中时执行此回调。调用时带有如下参数:

  • itemValue: 被选中项的value属性
  • itemPosition: 被选中项在picker中的索引位置

selectedValue 默认选中的值。可以是字符串或整数。

testID

用于在端对端测试中定位此视图。

enabled(Android特有) 如果设为false,则会禁用此选择器。

mode(Android特有)

在Android上,可以指定在用户点击选择器时,以怎样的形式呈现选项:

  • dialog(对话框形式): 显示一个模态对话框。默认选项。
  • dropdown(下拉框形式): 以选择器所在位置为锚点展开一个下拉框

prompt(Android特有)

设置选择器的提示字符串。在Android的对话框模式中用作对话框的标题。

itemStyle(ios特有)

指定应用在每项标签上的样式。

完整实例

基于上面的属性讲解,我们很容易实现一个Picker的效果。

代码:

代码语言:javascript复制
<Picker
            selectedValue={this.state.language}
            onValueChange={lang => this.setState({language:lang})}
            mode="dialog"
            style={{color:'#f00'}}
            >
            <Picker.Item label="Java" value="Java"/>
            <Picker.Item label="JavaScript" value="js"/>
            <Picker.Item label="C语音" value="c"/>
            <Picker.Item label="PHP开发" value="php"/>
          </Picker>

综合实例

首先看一个我们在项目中常见的效果图。一般我们的picker上边是取消和确定两个按钮,用来选中或者取消Picker的值,Picker一般会固定高度,然后实现一个拨盘滚动的效果,并且上部分有遮罩层。整个界面在出现或者消失的时候往往会伴随动画(一般用Animated实现)。

显示动画:

代码语言:javascript复制
in() {  
    Animated.parallel([  
      Animated.timing(  
        this.state.opacity,  
        {  
          easing: Easing.linear,  
          duration: 500,  
          toValue: 0.8,  
        }  
      ),  
      Animated.timing(  
        this.state.offset,  
        {  
          easing: Easing.linear,  
          duration: 500,  
          toValue: 1,  
        }  
      )  
    ]).start();  
  }  

//隐藏动画

代码语言:javascript复制
out(){  
    Animated.parallel([  
      Animated.timing(  
        this.state.opacity,  
        {  
          easing: Easing.linear,  
          duration: 500,  
          toValue: 0,  
        }  
      ),  
      Animated.timing(  
        this.state.offset,  
        {  
          easing: Easing.linear,  
          duration: 500,  
          toValue: 0,  
        }  
      )  
    ]).start();  

    this.timer = setTimeout(  
      () => this.setState({hide: true}),  
      500  
    );  
  }  

完整代码:

代码语言:javascript复制
'use strict';  
import React, { Component } from 'react';  
import {  
  StyleSheet,  
  View,  
  Image,  
  Text,  
  TouchableHighlight,  
  Animated,  
  Easing,  
  Dimensions,  
  Picker,  
  TouchableOpacity,  
} from 'react-native';  

const {width, height} = Dimensions.get('window');  
const navigatorH = 64; // navigator height  
const [aWidth, aHeight] = [width, 214];  
const [left, top] = [0, 0];  

const styles = StyleSheet.create({  
  container: {  
    position:"absolute",  
    width:width,  
    height:height,  
    left:left,  
    top:top,  
  },  
  mask: {  
    justifyContent:"center",  
    backgroundColor:"#383838",  
    opacity:0.8,  
    position:"absolute",  
    width:width,  
    height:height,  
    left:left,  
    top:top,  
  },  
  tip: {  
    width:aWidth,  
    height:aHeight,  
    // left:middleLeft,  
    backgroundColor:"#fff",  
    alignItems:"center",  
    justifyContent:"space-between",  
  },  
  tipTitleView: {  
    height:53,  
    width:aWidth,  
    flexDirection:'row',  
    alignItems:'center',  
    justifyContent:'space-between',  
    borderBottomWidth:0.5,  
    borderColor:"#f0f0f0",  

  },  
  cancelText:{  
    color:"#e6454a",  
    fontSize:16,  
    paddingLeft:30,  
  },  
  okText:{  
    color:"#e6454a",  
    fontSize:16,  
    paddingRight:27,  
    fontWeight:'bold',  
  },  
  picker:{  
    justifyContent:'center',  
    // height: 216,//Picker 默认高度  
    width:aWidth,  
  },  
  itempicker:{  
    color:'#e6454a',  
    fontSize:19,  
    height:161  
  }  
});  

export default class PickerWidget extends Component {  

  constructor(props) {  
    super(props);  
    this.state = {  
      offset: new Animated.Value(0),  
      opacity: new Animated.Value(0),  
      choice:this.props.defaultVal,  
      hide: true,  
    };  
    this.options = this.props.options;  
    this.callback = function () {};//回调方法  
    this.parent ={};  
  }  

  componentWillUnMount(){  
    this.timer && clearTimeout(this.timer);  
  }  

  render() {  
    if(this.state.hide){  
      return (<View />)  
    } else {  
      return (  
        <View style={styles.container} >  
          <Animated.View style={ styles.mask } >  
          </Animated.View>  

          <Animated.View style={[styles.tip , {transform: [{  
                translateY: this.state.offset.interpolate({  
                 inputRange: [0, 1],  
                 outputRange: [height, (height-aHeight)]  
                }),  
              }]  
            }]}>  
            <View style={styles.tipTitleView} >  
              <Text style={styles.cancelText} onPress={this.cancel.bind(this)}>取消</Text>  
              <Text style={styles.okText} onPress={this.ok.bind(this)} >确定</Text>  
            </View>  
            <Picker  
              style={styles.picker}  
              mode={Picker.MODE_DIALOG}  
              itemStyle={styles.itempicker}  
              selectedValue={this.state.choice}  
              onValueChange={choice => this.setState({choice: choice})}>  
                {this.options.map((aOption) =>  <Picker.Item color='#b5b9be' label={aOption} value={aOption} key={aOption} /> )}  
            </Picker>  
          </Animated.View>  
        </View>  
      );  
    }  
  }  

  componentDidMount() {  
  }  

  //显示动画  
  in() {  
    Animated.parallel([  
      Animated.timing(  
        this.state.opacity,  
        {  
          easing: Easing.linear,  
          duration: 500,  
          toValue: 0.8,  
        }  
      ),  
      Animated.timing(  
        this.state.offset,  
        {  
          easing: Easing.linear,  
          duration: 500,  
          toValue: 1,  
        }  
      )  
    ]).start();  
  }  

  //隐藏动画  
  out(){  
    Animated.parallel([  
      Animated.timing(  
        this.state.opacity,  
        {  
          easing: Easing.linear,  
          duration: 500,  
          toValue: 0,  
        }  
      ),  
      Animated.timing(  
        this.state.offset,  
        {  
          easing: Easing.linear,  
          duration: 500,  
          toValue: 0,  
        }  
      )  
    ]).start();  

    this.timer = setTimeout(  
      () => this.setState({hide: true}),  
      500  
    );  
  }  

  //取消  
  cancel(event) {  
    if(!this.state.hide){  
      this.out();  
    }  
  }  

  //选择  
  ok() {  
    if(!this.state.hide){  
      this.out();  
      this.callback.apply(this.parent,[this.state.choice]);  
    }  
  }  

  show(obj:Object,callback:Object) {  
    this.parent = obj;  
    this.callback = callback;  
    if(this.state.hide){  
      this.setState({ hide: false}, this.in);  
    }  
  }  
}        

0 人点赞