React Native 自定义控件之验证码和Toast
时间:2022-04-27
本文章向大家介绍React Native 自定义控件之验证码和Toast,主要内容包括自定义Toast、获取验证码、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
React Native通过近两年的迭代和维护,最新版本已经到了0.45.1。
话说回来,尽管迭代的挺快,但还是有很多坑,很多基础的组件和API还是不完善。
今天给大家带来的自定义小专题,其实对于React Native来说,自定义组件的过程更像是Android、iOS的组合控件。大体步骤有如下几个步骤(不完全准确,但是方向大体准确): 1,定义构造函数constructor; 2,定义组件属性propTypes; 3,绘制界面; 4,添加更新界面逻辑等
自定义Toast
在系统组件中,RN为我们提供了ToastAndroid组件,但是对于iOS好像并没有直接提供,这时候我们就想到了自定义控件了。如下图所示:
我们之前讲过Animated组件,这个组件可以实现渐变,缩放,旋转等动画效果,在这里,我们可以用它来实现Toast的功能。比如,显示两秒后消失,为了对显示的位置进行设置,我们还可以设置显示的位置,所以绘制render的代码如下:
render() {
let top;
switch (this.props.position){
case 'top':
top=160;
break;
case 'center':
top=height /2;
break;
case 'bottom':
top=height - 160;
break;
}
let view = this.state.isShow ?
<View
style={[styles.container,{top:top}]}
pointerEvents="none"
>
<Animated.View
style={[styles.content,{opacity:this.state.opacityValue}]}
>
<Text style={styles.text}>{this.state.text}</Text>
</Animated.View>
</View> : null;
return view;
}
显示时长控制方法:
show(text, duration) {
if(duration>=DURATION.LENGTH_LONG){
this.duration=DURATION.LENGTH_LONG;
}else {
this.duration=DURATION.LENGTH_SHORT;
}
this.setState({
isShow: true,
text: text,
});
this.isShow=true;
this.state.opacityValue.setValue(OPACITY)
this.close();
}
完整代码:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, {Component,PropTypes} from 'react';
import {
StyleSheet,
View,
Animated,
Dimensions,
Text,
} from 'react-native'
export const DURATION = {LENGTH_LONG: 2000, LENGTH_SHORT: 500};
const {height, width} = Dimensions.get('window');
const OPACITY=0.6;
const dismissKeyboard = require('dismissKeyboard')
export default class ToastUtil extends Component {
static propTypes = {
position: PropTypes.oneOf([
'top',
'center',
'bottom',
]),
}
static defaultProps = {
position:'center',
}
constructor(props) {
super(props);
this.state = {
isShow: false,
text: '',
opacityValue:new Animated.Value(OPACITY),
}
}
show(text, duration) {
if(duration>=DURATION.LENGTH_LONG){
this.duration=DURATION.LENGTH_LONG;
}else {
this.duration=DURATION.LENGTH_SHORT;
}
this.setState({
isShow: true,
text: text,
});
this.isShow=true;
this.state.opacityValue.setValue(OPACITY)
this.close();
}
close() {
if(!this.isShow)return;
this.timer && clearTimeout(this.timer);
this.timer = setTimeout(() => {
Animated.timing(
this.state.opacityValue,
{
toValue: 0.0,
duration:1000,
}
).start(()=>{
this.setState({
isShow: false,
});
this.isShow=false;
});
}, this.duration);
}
componentWillUnmount() {
this.timer && clearTimeout(this.timer);
}
render() {
let top;
switch (this.props.position){
case 'top':
top=160;
break;
case 'center':
top=height /2;
break;
case 'bottom':
top=height - 160;
break;
}
let view = this.state.isShow ?
<View
style={[styles.container,{top:top}]}
pointerEvents="none"
>
<Animated.View
style={[styles.content,{opacity:this.state.opacityValue}]}
>
<Text style={styles.text}>{this.state.text}</Text>
</Animated.View>
</View> : null;
return view;
}
}
const styles = StyleSheet.create({
container: {
position: 'absolute',
left: 0,
right: 0,
alignItems: 'center',
},
content: {
backgroundColor: 'black',
opacity: OPACITY,
borderRadius: 5,
padding: 10,
},
text:{
color:'white'
},
})
如何使用:
<Toast ref="toast"/>
//省略...
<Text style={styles.styleText} onPress={()=>{
this.refs.toast.show('你点击了忘记密码!',3000);}}>
忘记密码?
</Text>
//省略...
获取验证码
在很多应用开发中都会涉及到获取手机验证码的场景,例如登录或者注册获取验证码。如下图:
那么按照自定义组件的流程,先添加构造函数,并定义必须的一些字段(相关属性),并完成初始化:
static propTypes = {
style: PropTypes.object,//style属性
textStyle: Text.propTypes.style,//文本文字
onClick: PropTypes.func,//点击事件
disableColor: PropTypes.string,//倒计时过程中颜色
timerTitle: PropTypes.string,//倒计时文本
enable: React.PropTypes.oneOfType([React.PropTypes.bool,React.PropTypes.number])
};
2,构造函数:
constructor(props) {
super(props)
this.state = {
timerCount: this.props.timerCount || 60,//默认倒计时时间
timerTitle: this.props.timerTitle || '获取验证码',
counting: false,
selfEnable: true,
};
this.shouldStartCountting = this.shouldStartCountting.bind(this)
this.countDownAction = this.countDownAction.bind(this)
}
3,添加绘制界面代码:
render() {
const {onClick, style, textStyle, disableColor} = this.props;
const {counting, timerTitle, selfEnable} = this.state;
return (
<TouchableOpacity activeOpacity={counting ? 1 : 0.8} onPress={() => {
if (!counting &&selfEnable) {
this.setState({selfEnable: false});
this.shouldStartCountting(true);
};
}}>
<View
style={styles.styleCodeView}>
<Text
style={[{fontSize: 12}, textStyle, {color: ((!counting && selfEnable) ? textStyle.color : disableColor || 'gray')}]}>{timerTitle}</Text>
</View>
</TouchableOpacity>
)
}
4,添加逻辑代码:
shouldStartCountting(shouldStart) {
if (this.state.counting) {
return
}
if (shouldStart) {
this.countDownAction()
this.setState({counting: true, selfEnable: false})
} else {
this.setState({selfEnable: true})
}
}
//倒计时逻辑
countDownAction() {
const codeTime = this.state.timerCount;
this.interval = setInterval(() => {
const timer = this.state.timerCount - 1
if (timer === 0) {
this.interval && clearInterval(this.interval);
this.setState({
timerCount: codeTime,
timerTitle: this.props.timerTitle || '获取验证码',
counting: false,
selfEnable: true
})
} else {
this.setState({
timerCount: timer,
timerTitle: `重新获取(${timer}s)`,
})
}
}, 1000)
}
说明: shouldStartCountting:回调函数,接受一个Bool类型的参数 1,shouldStartCountting(true),开始倒计时,倒计时结束时自动恢复初始状态 2,shouldStartCountting(false), 按钮的selfEnable会立即被置为true 所以,获取验证码的完整代码如下:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, {Component,PropTypes} from 'react';
import {
Text,
StyleSheet,
View,
TouchableOpacity,
} from 'react-native';
var Dimensions = require('Dimensions');
var screenWidth = Dimensions.get('window').width;
export default class TimerButton extends Component {
constructor(props) {
super(props)
this.state = {
timerCount: this.props.timerCount || 60,
timerTitle: this.props.timerTitle || '获取验证码',
counting: false,
selfEnable: true,
};
this.shouldStartCountting = this.shouldStartCountting.bind(this)
this.countDownAction = this.countDownAction.bind(this)
}
static propTypes = {
style: PropTypes.object,
textStyle: Text.propTypes.style,
onClick: PropTypes.func,
disableColor: PropTypes.string,
timerTitle: PropTypes.string,
enable: React.PropTypes.oneOfType([React.PropTypes.bool,React.PropTypes.number])
};
countDownAction() {
const codeTime = this.state.timerCount;
this.interval = setInterval(() => {
const timer = this.state.timerCount - 1
if (timer === 0) {
this.interval && clearInterval(this.interval);
this.setState({
timerCount: codeTime,
timerTitle: this.props.timerTitle || '获取验证码',
counting: false,
selfEnable: true
})
} else {
this.setState({
timerCount: timer,
timerTitle: `重新获取(${timer}s)`,
})
}
}, 1000)
}
shouldStartCountting(shouldStart) {
if (this.state.counting) {
return
}
if (shouldStart) {
this.countDownAction()
this.setState({counting: true, selfEnable: false})
} else {
this.setState({selfEnable: true})
}
}
componentWillUnmount() {
clearInterval(this.interval)
}
render() {
const {onClick, style, textStyle, disableColor} = this.props;
const {counting, timerTitle, selfEnable} = this.state;
return (
<TouchableOpacity activeOpacity={counting ? 1 : 0.8} onPress={() => {
if (!counting &&selfEnable) {
this.setState({selfEnable: false});
this.shouldStartCountting(true);
};
}}>
<View
style={styles.styleCodeView}>
<Text
style={[{fontSize: 12}, textStyle, {color: ((!counting && selfEnable) ? textStyle.color : disableColor || 'gray')}]}>{timerTitle}</Text>
</View>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 20
},
styleCodeView: {
height: 28,
width: screenWidth*0.22,
borderColor: '#dc1466',
borderWidth: 1,
borderRadius: 5,
justifyContent: 'center',
alignItems: 'center',
},
styleTextCode: {
fontSize: 12,
color: '#dc1466',
textAlign: 'center',
},
});
如何使用?
import TimerButton from './TimerButton'
var Dimensions = require('Dimensions');
var screenWidth = Dimensions.get('window').width;
//省略...
<TimerButton
style={{width: screenWidth*0.2,marginRight: 10}}
timerCount={60}
textStyle={{color: '#dc1466'}}
onclick={(start)=>{
}}/>
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Tomcat部署SpringBoot war包
- Vue之插槽Slot理解
- Docker六脉神剑 (三) 编写Dockerfile构建nginx镜像并推送到远程仓库给其他人使用
- 快速学习UML类图查看
- 设计模式 | 抽象工厂模式
- 设计模式 | 单例模式
- macOS 安装软件已损坏无法打开解决办法 (真好用!)
- nginx 配置反向代理
- ES6新特性速查表
- React-Native Android打包
- React-Native iOS打包
- Webpack+Babel手把手带你搭建开发环境(内附配置文件)
- Redux 异步解决方案2. Redux-Saga中间件
- Redux异步解决方案 1. Redux-Thunk中间件
- 深度学习Pytorch检测实战 - Notes - 第1&2章 基础知识