• React Native之(支持iOS与Android)自定义单选按钮(RadioGroup,RadioButton)


    React Native之(支持iOS与Android)自定义单选按钮(RadioGroup,RadioButton)

    一,需求与简单介绍

       在开发项目时发现RN没有给提供RadioButton和RadioGroup这两个组件,只有CheckBox组件(不支持iOS),但是项目中确实有有一些地方需要使用到RadioButton和RadioGroup,比如默认地址的选择等。

       需求:

    • 可以指定选中状态和未选中状态的颜色。
    • 可以指定该单选按钮是否可选:disabled。
    • 可以指定整体的样式,就像使用系统组件一样,这个用style来接收。
    • 可以自定义宽(width)高(height)。

    二,RadioButton(如需完整的代码,请留言评论)

        在RN中控制一个View动态改变需要使用到state,这里定义一个state变量selected来记录RadioButton是否被选中,并且可以默认选中某一个,为true为选中状态,false为未选中状态:(如需完整的代码,请留言评论)

    1 this.setState({
    2     selectedIndex: nextProps.selectedIndex//从RadioGroup组件传入
    3 })

        state变量和动态控制一个组件的改变,但是组件改变之前仍然可能会显示一些东西,这些东西用props来控制,而且可以用这些props定义一些默认的属性,例如我们可以定义默认的颜色等:

    1 RadioGroup.defaultProps = {
    2     size: defaultSize,
    3     thickness: defaultThickness,
    4     color: defaultColor,
    5     highlightColor: null,
    6 }

       
        在使用时我们可能会给这个RadioButton添加style属性,例如单选按钮的宽,高颜色等,以及选中的小圆点颜色,宽,高等等等,这个是在外面设置的,在内部我们同样会设置style属性

     1  getRadioStyle(){
     2         return {
     3             height: this.context.size,
     4              this.context.size,
     5             borderRadius: this.context.size / 2,
     6             borderWidth: this.context.thickness,
     7             borderColor: this.props.isSelected && this.props.activeColor?this.props.activeColor:this.context.color,
     8         }
     9     }
    10 
    11     getRadioDotStyle(){
    12         return {
    13             height: this.context.size / 2,
    14              this.context.size / 2,
    15             borderRadius: this.context.size / 4,
    16             backgroundColor: this.props.color || this.props.activeColor,
    17         }
    18     }

        给最外层的View添加TouchableWithoutFeedback组件,添加点击事件以及是否可点击状态:

    1  <View style={{opacity: this.props.disabled?0.4:1}}>
    2                 <TouchableWithoutFeedback
    3                     disabled={this.props.disabled}//是否可点击
    4                     onPress={() => this.context.onSelect(this.props.index, this.props.value)}//选中事件
    5                 >
    6                             {children}
    7             </TouchableWithoutFeedback>
    8   </View>

        选中之后的样式选择:(如需完整的代码,请留言评论)

    1  isSelected(){
    2         if(this.props.isSelected)
    3             return <View style={this.getRadioDotStyle()}/>
    4  }

    三,RadioGroup(如需完整的代码,请留言评论)

        使用RadioButton大部分情况是多个共同使用,而且只能有一个被选中,android中就有这样的组件,但是在RN中没有找到,其实这个也很容易实现,原理是通过RadioGroup来生成多个RadioButton并且持有这些RadioButton的引用,当一个被选中的时候把其他的置为不选中(如需完整的代码,请留言评论)。

    1 if(nextProps.selectedIndex != this.prevSelected){
    2             this.prevSelected = nextProps.selectedIndex
    3             this.setState({
    4                 selectedIndex: nextProps.selectedIndex
    5             })
    6 }

        使用RadioGroup时给这个RadioButton传递多个即可,然后RadioGroup通过数组来创建RadioGroup,因为同样要指定RadioButton的样式,所以在外部使用时直接把style的各种样式和属性一并传递给RadioGroup,RadioGroup在创建RadioButton时把这些样式属性再传递给RadioButton(如需完整的代码,请留言评论):

     1 <View style={this.props.style}>
     2                 {radioButtons}
     3  </View>
     4 RadioGroup.childContextTypes = {
     5     onSelect: PropTypes.func.isRequired,
     6     size: PropTypes.number.isRequired,
     7     thickness: PropTypes.number.isRequired,
     8     color: PropTypes.string.isRequired,
     9     activeColor: PropTypes.string,
    10     highlightColor: PropTypes.string,
    11 }

        获取选中事件的函数(如需完整的代码,请留言评论):

    1 onSelect(index, value){
    2 this.setState({
    3 selectedIndex: index
    4 })
    5 if(this.props.onSelect)
    6 this.props.onSelect(index, value)
    7 }

    四,使用实例(如需完整的代码,请留言评论)

        已实现的样列(如需完整的代码,请留言评论):

        组件代码实现:

     1   <RadioGroup
     2                             style={{ backgroundColor: '#fff' }}
     3                             onSelect={(index, value) => this.onSelect(index, value)}
     4                             selectedIndex={this.state.selectedIndex}
     5                         >
     6                             {UsersAddress.map((model, i) => {
     7 
     8                                 return (
     9                                     <RadioButton
    10                                         key={i}
    11                                         value={model}
    12                                         selectedIndex={1}
    13                                         style={{ backgroundColor: '#fff', marginBottom: 12, borderBottomColor: '#e4e4e4', borderBottomWidth: 12 }}>
    14  <Text>张三</Text>
    15   </RadioButton> 
    16  <RadioButton
    17                                         key={i}
    18                                         value={model}
    19                                         selectedIndex={1}
    20                                         style={{ backgroundColor: '#fff', marginBottom: 12, borderBottomColor: '#e4e4e4', borderBottomWidth: 12 }}>
    21  <Text>李四</Text>
    22   </RadioButton> 
    23  <RadioButton
    24                                         key={i}
    25                                         value={model}
    26                                         selectedIndex={1}
    27                                         style={{ backgroundColor: '#fff', marginBottom: 12, borderBottomColor: '#e4e4e4', borderBottomWidth: 12 }}>
    28  <Text>王二</Text>
    29   </RadioButton> 
    30 </RadioGroup>
    1  onSelect(index, value) {
    2         //alert(JSON.stringify(value))
    3         //this.openAduice()
    4         this.setState({
    5             text: `Selected index: ${index} , value: ${value}`,
    6             addressId: value.id
    7         })
    8     }

    (如需完整的代码,请留言评论,留下联系方式)

  • 相关阅读:
    实操ES6之Promise
    RabbitMQ入门指南
    【从零开始撸一个App】PKCE
    SpringCloud Alibaba Nacos Config 配置中心
    SpringCloud Alibaba Nacos 服务发现 Feign进行消费
    SpringCloud Alibaba Nacos 服务发现 RestTemplate进行消费
    SpringCloud Alibaba Nacos 服务注册
    SpringCloud Alibaba Nacos 服务治理中心
    开发者-管理者 设计陷阱
    java8中的Stream API实战
  • 原文地址:https://www.cnblogs.com/jackson-yqj/p/9528382.html
Copyright © 2020-2023  润新知