使用React Native實現Button的效果:
0. 概述
使用React Native的TouchableHighlight組件包裝Text、Image或其他組件。因爲TouchableHighlight有onPress回調方法,可以處理點擊事件。
1. Basic Button實現
使用TouchableHightlight的屬性/方法:
onPress:處理點擊事件
underlayColor:點擊時TouchableHightlight的顏色
實現代碼:
// 普通按鈕效果。
//點擊時只改變背景色而不改變字體等樣式,只需使用 TouchableHighlight 中的 underlayColor 屬性
class BasicButton extends Component {
render(){
return(
<TouchableHighlight
style={styles.exit}
underlayColor="#d9d9d9"
onPress={() => {
console.log('Press Basic Button!');
}}>
<Text style={styles.exittext}>
Basic Button
</Text>
</TouchableHighlight>
);
}
}
2. Change Style Button
使用TouchableHighlight的屬性/方法:
onPress:處理點擊事件
underlay:點擊時underlay的顏色
onHideUnderlay:當underlay隱藏時會調用此方法。可以用來處理沒有Touch按鈕時的樣式。
onShowUnderlay:當underlay顯示時會調用此方法。可以用了處理Touch按鈕時的樣式。
實現代碼:
// 點擊時改變背景色同時改變按鈕的字體顏色
// 需要使用TouchableHighlight的onHideUnderlay和onShowUnderlay屬性
const RED_COLOR = 'red';
const WHITE_COLOR = 'white';
class ChangeStyleButton extends Component {
constructor(props) {
super(props);
this.state = { pressStatus: false };
}
_onHideUnderlay(){
this.setState({ pressStatus: false });
}
_onShowUnderlay(){
this.setState({ pressStatus: true });
}
render(){
return(
<TouchableHighlight
onHideUnderlay={this._onHideUnderlay.bind(this)}
onPress={() => {
console.log('Press Change Style Button');
}}
onShowUnderlay={this._onShowUnderlay.bind(this)}
style={[styles.exit, this.state.pressStatus ? {backgroundColor: RED_COLOR} : {backgroundColor: WHITE_COLOR}]}
underlayColor='red'>
<Text style={[styles.exittext, this.state.pressStatus ? {color: WHITE_COLOR} : {color: RED_COLOR}]}>
Change Style Button
</Text>
</TouchableHighlight>
);
}
}
3. 單選按鈕
實現代碼:
class RedioButton extends Component {
constructor(props) {
super(props);
this.state = {
isAllSelected: false,
isNotDealSelected: true,
isDealedSelected: false,
}
}
// 更新"全部/未處理/已處理"按鈕的狀態
_updateBtnSelectedState(currentPressed, array) {
if (currentPressed === null || currentPressed === 'undefined' || array === null || array === 'undefined') {
return;
}
let newState = {...this.state};
for (let type of array) {
if (currentPressed == type) {
newState[type] ? {} : newState[type] = !newState[type];
this.setState(newState);
} else {
newState[type] ? newState[type] = !newState[type] : {};
this.setState(newState);
}
}
}
// 返回設置的button
_getButton(style, selectedSate, stateType, buttonTitle, count) {
let BTN_SELECTED_STATE_ARRAY = ['isAllSelected', 'isNotDealSelected', 'isDealedSelected'];
return(
<View style={[style, selectedSate ? {backgroundColor: '#32a7f5'} : {}]}>
<Text
style={[styles.button, selectedSate ? {color: 'white'} : {}]}
onPress={ () => {this._updateBtnSelectedState(stateType, BTN_SELECTED_STATE_ARRAY)}}>
{buttonTitle}({count})
</Text>
</View>
);
}
render(){
return(
<View style={styles.buttonlayout}>
{this._getButton(styles.buttonleft, this.state.isAllSelected, 'isAllSelected', 'Btn_1', 10)}
<View style={styles.buttondivideline}></View>
{this._getButton(null, this.state.isNotDealSelected, 'isNotDealSelected', 'Btn_1', 20)}
<View style={styles.buttondivideline}></View>
{this._getButton(styles.buttonright, this.state.isDealedSelected, 'isDealedSelected', 'Btn_1', 30)}
</View>
);
}
}
4. 上面案例中用的Style
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
exit: {
width: 380,
height: 50,
marginTop: 30,
alignItems: 'center',
borderColor: 'red',
borderWidth: 1,
borderStyle: 'solid',
borderRadius: 5,
},
exittext: {
height: 50,
fontSize: 18,
textAlignVertical: 'center',
},
buttonlayout: {
height: 30,
marginTop: 30,
alignSelf: 'center',
flexDirection: 'row',
alignItems: 'center',
borderColor: '#32a7f5',
borderWidth: 1,
borderStyle: 'solid',
borderRadius: 8,
},
buttonleft: {
borderTopLeftRadius: 8,
borderBottomLeftRadius: 8,
},
buttonright: {
borderTopRightRadius: 8,
borderBottomRightRadius: 8,
},
button: {
height: 30,
textAlign: 'center',
textAlignVertical: 'center',
paddingLeft: 10,
paddingRight: 10,
},
buttondivideline: {
width: 1,
height: 30,
backgroundColor: '#32a7f5',
flexDirection: 'column',
},
});