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     }

(如需完整的代碼,請留言評論,留下聯系方式)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM