React Native 自定義控制元件之驗證碼和Toast
React Native通過近兩年的迭代和維護,最新版本已經到了0.45.1,關於最新版本的介紹請檢視我之前的部落格:0.45新特性。話說回來,儘管迭代的挺快,但還是有很多坑,很多基礎的元件和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)=>{
}}/>
相關推薦
React Native 自定義控制元件之驗證碼和Toast
React Native通過近兩年的迭代和維護,最新版本已經到了0.45.1,關於最新版本的介紹請檢視我之前的部落格:0.45新特性。話說回來,儘管迭代的挺快,但還是有很多坑,很多基礎的元件和API還是不完善。 今天給大家帶來的自定義小專題,其實對於React
react-native自定義控制元件怎麼實現螢幕寬度的80%
原來我們講過在定義PixelRatio後可以獲取螢幕的寬度,程式碼如下: var width = Dimensions.get(‘window’).width; 然後在類CSS樣式中採用:widt
自定義控制元件之側滑關閉 Activity 控制元件
隔壁 iOS 的小夥伴有一個功能就是左手向右手一個慢動作,輕輕一劃就可以關閉介面,這種操作感覺還是很絲滑的,而且這還是 iOS 系統自帶的功能,由於 Android 手機早期是有 back 鍵,home 鍵 和選單鍵(現在大部分手機都只保留一個鍵了),所以 Android 是沒有這個功能的。現在
自定義控制元件之下載控制元件1(DownloadView1)
前段時間在乾貨集中營看到了兩個炫酷的下載按鈕: 可惜是隔壁 iOS 的孩子,怎麼辦,我也好喜歡,emmm,某該,只能自己模仿著實現一下了。先從第一個入手(第二個波浪效果暫時還不會)。 1 準備動作 寫過幾次自定義控制元件
自定義控制元件之 PasswordEditText(密碼輸入框)
前兩天在掘金上看到了一個驗證碼輸入框,然後自己實現了一下,以前都是繼承的 View,這次繼承了 ViewGroup,也算是嘗試了一點不同的東西。先看看最終效果: 事實上就是用將輸入的密碼用幾個文字框來顯示而已,要打造這樣一個東西我剛開始也是一頭霧水,不急,直接寫不會,我們可以採取曲線救
自定義控制元件之 Gamepad (遊戲手柄)
這段時間自己在復刻一個小時候玩過的小遊戲——魔塔,在人物操控的時候剛開始用的感覺 low low 的上下左右四個方向鍵,後來受王者農藥啟發,決定採用現在很多遊戲中的那種遊戲手柄,網上也有例子,不過最近自己對自定義控制元件很感興趣,決定自己擼一個,最後實現的效果是這樣的: 看到這樣
自定義控制元件之 SubmitBotton (提交按鈕)
在 Android 中我覺得除了實現很多功能性很強的需求之外,最吸引我的就是各種炫酷的自定義控制元件,但是自定義控制元件這個東西沒有辦法用一種固定的模式來講解,因為自定義控制元件都是根據需求來定製的。同時這也說明只要程式猿牛逼,就沒有實現不了的功能。 之前有看到一個效果: Android
react-native自定義原生元件
此文已由作者王翔授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。 使用react-native的時候能夠看到不少函式呼叫式的元件,像LinkIOS用來呼起url請求 LinkIOS.openUrl('http://www.163.com'); ac
自定義控制元件之固定Tab
在開發中我們通常用到固定的Tab,Tab的個數是可以動態配置的,但是不支援滑動,每個Tab均分佈局並且之間被一個豎線分割開,Tab底部是一條分割線。看到如下效果如下,Tab佈局、線條顏色都支援高度制定。這個Tab的難點在於首先Tab個數不固定,其次Tab豎線左右兩端沒有隻有相鄰的兩個才有,而且粗
wpf自定義控制元件之依賴屬性
在wpf開發過程中,總會用到格式各樣的控制元件,但是原生控制元件遠遠不能滿足實際開發的需要,這時候wpf強大之處就能體現出來了。根據實際需求自定義各種不同的控制元件滿足不同的業務需求。 首先說需求吧: 一:根據某個bool值,控制一個圓形控制元件顯示或者不顯示某種顏色。 分析: 一:需
Android自定義控制元件之區域性圖片放大鏡--BiggerView
零、前言: 本文的知識點一覽 1.自定義控制元件及自定義屬性的寫法,你也將對onMesure有更深的認識 2.關於bitmap的簡單處理,及canvas區域裁剪 3.本文會實現兩個自定義控制元件:FitImageView(圖片自適應)和BiggerView(放大鏡),前者為後者作為鋪墊。 4.最後會
自定義控制元件之輪播圖的實現
public class BannerView extends RelativeLayout { private boolean startAndclose; private List<String> images = new ArrayList
【我的Android進階之旅】自定義控制元件之使用ViewPager實現可以預覽的畫廊效果,並且自定義畫面切換的動畫效果的切換時間
我們來看下效果 在這裡,我們實現的是,一個ViewPager來顯示圖片列表。這裡一個頁面,ViewPage展示了前後的預覽,我們讓預覽頁進行Y軸的壓縮,並設定透明度為0.5f,所有我們看到gif最後,左右兩邊的圖片有點朦朧感。讓預覽頁和主頁面有主從感。我們用分
Android自定義控制元件之仿汽車之家下拉重新整理
關於下拉重新整理的實現原理我在上篇文章Android自定義控制元件之仿美團下拉重新整理中已經詳細介紹過了,這篇文章主要介紹錶盤的動畫實現原理 汽車之家的下拉重新整理分為三個狀態: 第一個狀態為下拉重新整理狀態(pull to refresh),在這個狀
自定義控制元件之組合式控制元件 下拉選擇框
自定義控制元件之組合式控制元件 下拉選擇框 文章目錄 自定義控制元件之組合式控制元件 下拉選擇框 零 組合控制元件下載 一 自定義控制元件思路 二 MainActivity核心程式碼 三 activity_main.xml
自定義控制元件之二階貝塞爾曲線方法詳解
前言:先膜拜一下啟艦大神,本想自己寫一篇關於貝塞爾曲線的文章,但無奈此大神寫的太6了 ,所以直接轉載 相關文章:《Android自定義控制元件三部曲文章索引》: http://blog.csdn.net/harvic880925/article/details/50995268從
自定義控制元件之文字繪製
paint與文字設定相關的方法如下 paint.setStrokeWidth(5);//畫筆寬度 paint.setColor(Color.RED);//設定顏色 paint.setAntiAlias(true);//抗鋸齒功能 p
Winform----自定義控制元件之背景半透明遮罩載入控制元件
先貼執行效果圖,原始碼點選這裡下載 1.新建自定義控制元件 2.實現功能 namespace UserControlLib { [ToolboxBitmap(typeof(ZhLoading))] public partial class ZhLoad
Android自定義控制元件之《折線圖的繪製》
金融軟體裡的行情分時圖,這是我們最常見的折線圖,當然了,折線圖的用途並不僅僅侷限於此,像一般在一定區間內,為了更好的能顯示出幅度的變化,那麼用折線圖來展示無疑是最符合效果的,當然了,網上也有很多的第
Android自定義控制元件之實現滑動選擇開關
前言:今天我們仿照著Google給我們提供的Switch控制元件來進行一次模仿,自己動手打造一個可以換滑動圖片以及背景的圖片。 -----------------分割線--------------- 先看一下google提供的Switc控制元件: 其實用法很簡單就當普通的