共计 4355 个字符,预计需要花费 11 分钟才能阅读完成。
react-native, 安全 纯数字键盘组件;
所需依赖原生 react-native 和 ant-design RN;
代码比较简单,有这方面需求的小伙伴可以 copy 随时使用;
可以根据自己实际业务场景作修改
使用
<Keyboard
type='deal'//verify,deal
title={'請輸入交易密碼'}
keyboardVisible={this.state.keyboardVisible}
toClose={this.onKeyboard}
getPasswordstr={(str) => {console.log(str) }}
getPasswordArr={(arr) => {console.log(arr) }}
forgot={() => { console.log(1111) }}
/>
源码
import React, {Component} from 'react';
import {StyleSheet, Text, View, Modal, Dimensions} from 'react-native';
import {Grid, Icon} from '@ant-design/react-native';
let width = Dimensions.get('window').width;// 获取设备的宽高
let height = Dimensions.get('window').height;
let i = 0;
export default class Keyboard extends Component {
static navigationOptions = {header: null}
constructor(props) {super(props);
this.state = {keyData: [],
hideBg: [],
currentIndex: undefined
}
}
componentDidMount() {this.defaultHideDom();
}
configItemEl(_el, index) {const { currentIndex} = this.state;
if (index <= 8) {return (<Text style={currentIndex === index ? styles.active : null}>{index + 1}</Text>);
}
if (index === 9) {return (<Text style={{ width: width / 3, height: 50, backgroundColor: '#CCC'}}></Text>);
}
if (index === 10) {return (<Text style={currentIndex === index ? styles.active : null}>0</Text>);
}
if (index === 11) {return (<Text style={{ color: '#0080FF', width: width / 3, height: 50, backgroundColor: '#CCC', textAlign: 'center', lineHeight: 50}}>DELETE</Text>);
}
}
defaultHideDom() {
this.setState({hideBg: Array.from(new Array(6)).map((_val, i) => ({text: <View style={styles.showPW} key={i}></View>,
}))
})
}
onKeyClick(index, i) {
const getPasswordstr = this.props.getPasswordstr;
const getPasswordArr = this.props.getPasswordArr;
if (index !== 12 && index !== 10 && this.state.keyData.length < 6) {
this.setState({keyData: [...this.state.keyData, index === 11 ? 0 : index],
hideBg: this.state.hideBg.map((item, indexKey) => {if (indexKey === i - 1) {item.text = (<View style={styles.showPW}>
<Text style={styles.passWorld}></Text>
</View>)
}
return item
})
}, () => {if (i === 6) {getPasswordstr(this.state.keyData.join(''));
}
getPasswordArr(this.state.keyData);
});
}
if (index === 12 && this.state.keyData.length >= 0) {const arr = this.state.keyData.filter((item, indexKey) => i !== indexKey)
this.setState({
keyData: arr,
hideBg: this.state.hideBg.map((item, indexKey) => {if (indexKey === i) {item.text = (<View style={styles.showPW}></View>)
}
return item
})
}, () => {getPasswordstr(this.state.keyData.join(''));
getPasswordArr(this.state.keyData);
})
}
}
render() {
const visible = this.props.keyboardVisible;
const type = this.props.type;
const title = this.props.title;
const toClose = this.props.toClose;
const forgot = this.props.forgot;
const {hideBg} = this.state;
return (
<Modal
visible={visible}
animationType="slide"
transparent={true}
onRequestClose={() => {
i = 0;
this.defaultHideDom();
this.setState({keyData: [] });
return toClose();}}
>
<View style={styles.container}>
<View style={styles.header}>
<Text onPress={() => {
i = 0;
this.defaultHideDom();
this.setState({keyData: [] });
toClose()}} style={styles.iconContainer}><Icon name='close' /></Text>
<Text>{title}</Text>
<Text style={styles.forgot} onPress={() => { forgot() }}> 忘記密碼 </Text>
</View>
{type === 'deal' && (<Grid
data={hideBg}
columnNum={6}
hasLine={false}
itemStyle={{
justifyContent: 'center',
alignItems: 'center',
flex: 1,
height: 80,
backgroundColor: '#FFF',
}}
renderItem={(_el, index) => _el.text}
/>)}
<Grid
data={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}
columnNum={3}
onPress={(_el, index) => {this.setState({ currentIndex: index}, () => {setTimeout(() => {this.setState({ currentIndex: undefined}) }, 10)
});
if (_el !== 12 && _el !== 10 && i < 6) {i++}
if (_el === 12 && i > 0) {i--}
this.onKeyClick(_el, i)
}}
itemStyle={{
justifyContent: 'center',
alignItems: 'center',
flex: 1,
height: 50,
backgroundColor: '#FFF'
}}
renderItem={(_el, index) =>
this.configItemEl(_el, index)
}
/>
</View>
</Modal>
);
}
}
const styles = StyleSheet.create({
active: {
width: width / 3,
height: 50,
backgroundColor: '#0080FF',
color: '#FFF',
textAlign: 'center',
lineHeight: 50
},
forgot: {
marginRight: 10,
color: '#0080FF',
fontSize: 12,
fontWeight: null
},
passWorld: {
borderRadius: 10,
width: 10,
height: 10,
backgroundColor: '#ccc'
},
showPW: {
justifyContent: 'center',
alignItems: 'center',
borderColor: '#CCC',
borderWidth: 1,
borderStyle: 'solid',
width: 25,
height: 25
},
iconContainer: {
width: 25,
height: 25,
marginLeft: 10
},
header: {
width: width,
height: 45,
flexWrap: 'nowrap',
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: '#FFF',
flexDirection: 'row',
alignContent: 'space-around',
borderBottomWidth: 1,
borderStyle: 'solid',
borderBottomColor: '#EAEAEA'
},
container: {
width: width,
height: height,
justifyContent: 'flex-end',
alignItems: 'flex-end',
backgroundColor: 'rgba(0,0,0,0.4)',
position: 'absolute',
top: -25
},
});
正文完
发表至: react-native
2019-06-26