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             width: 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             width: 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     }

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

 

转载于:https://www.cnblogs.com/jackson-yqj/p/9528382.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值