国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

ReactNative實現Toast的示例

2024-05-06 16:41:42
字體:
來源:轉載
供稿:網友

對于Android開發工程師來說,Toast在熟悉不過了,用它來顯示一個提示信息,并自動隱藏。在我們開發RN應用的時候,我門也要實現這樣的效果,就一點困難了,倒也不是困難,只是需要我們去適配,RN官方提供了一個API ToastAndroid,看到這個名字應該猜出,它只能在Android中使用,在iOS中使用沒有效果,所以,我們需要適配或者我們自定義一個,今天的這篇文章就是自定義一個Toast使其在Android和iOS都能運行,并有相同的運行效果。

源碼傳送門

定義組件

import React, {Component} from 'react';import {  StyleSheet,  View,  Easing,  Dimensions,  Text,  Animated} from 'react-native';import PropTypes from 'prop-types';import Toast from "./index";const {width, height} = Dimensions.get("window");const viewHeight = 35;class ToastView extends Component {  static propTypes = {    message:PropTypes.string,  };  dismissHandler = null;  constructor(props) {    super(props);    this.state = {      message: props.message !== undefined ? props.message : ''    }  }  render() {    return (      <View style={styles.container} pointerEvents='none'>        <Animated.View style={[styles.textContainer]}><Text          style={styles.defaultText}>{this.state.message}</Text></Animated.View>      </View>    )  }  componentDidMount() {    this.timingDismiss()  }  componentWillUnmount() {    clearTimeout(this.dismissHandler)  }  timingDismiss = () => {    this.dismissHandler = setTimeout(() => {      this.onDismiss()    }, 1000)  };  onDismiss = () => {    if (this.props.onDismiss) {      this.props.onDismiss()    }  }}const styles = StyleSheet.create({  textContainer: {    backgroundColor: 'rgba(0,0,0,.6)',    borderRadius: 8,    padding: 10,    bottom:height/8,    maxWidth: width / 2,    alignSelf: "flex-end",  },  defaultText: {    color: "#FFF",    fontSize: 15,  },  container: {    position: "absolute",    left: 0,    right: 0,    top: 0,    bottom: 0,    flexDirection: "row",    justifyContent: "center",  }});export default ToastView

首先導入我們必須的基礎組件以及API,我們自定義組件都需要繼承它,Dimensions用于實現動畫,Easing用于設置動畫的軌跡運行效果,PropTypes用于對屬性類型進行定義。

render方法是我們定義組件渲染的入口,最外層view使用position為absolute,并設置left,right,top,bottom設置為0,使其占滿屏幕,這樣使用Toast顯示期間不讓界面監聽點擊事件。內層View是Toast顯示的黑框容器,backgroundColor屬性設置rgba形式,顏色為黑色透明度為0.6。并設置圓角以及最大寬度為屏幕寬度的一半。然后就是Text組件用于顯示具體的提示信息。

我們還看到propTypes用于限定屬性message的類型為string。constructor是我們組件的構造方法,有一個props參數,此參數為傳遞過來的一些屬性。需要注意,構造方法中首先要調用super(props),否則報錯,在此處,我將傳遞來的值設置到了state中。

對于Toast,顯示一會兒自動消失,我們可以通過setTimeout實現這個效果,在componentDidMount調用此方法,此處設置時間為1000ms。然后將隱藏毀掉暴露出去。當我們使用setTimeout時還需要在組件卸載時清除定時器。組件卸載時回調的時componentWillUnmount。所以在此處清除定時器。

實現動畫效果

在上面我們實現了Toast的效果,但是顯示和隱藏都沒有過度動畫,略顯生硬。那么我們加一些平移和透明度的動畫,然后對componentDidMount修改實現動畫效果

在組件中增加兩個變量

moveAnim = new Animated.Value(height / 12);  opacityAnim = new Animated.Value(0);

在之前內層view的樣式中,設置的bottom是height/8。我們此處將view樣式設置如下

style={[styles.textContainer, {bottom: this.moveAnim, opacity: this.opacityAnim}]}

然后修改componentDidMount

componentDidMount() {    Animated.timing(      this.moveAnim,      {        toValue: height / 8,        duration: 80,        easing: Easing.ease      },    ).start(this.timingDismiss);    Animated.timing(      this.opacityAnim,      {        toValue: 1,        duration: 100,        easing: Easing.linear      },    ).start();  }

也就是bottom顯示時從height/12到height/8移動,時間是80ms,透明度從0到1轉變執行時間100ms。在上面我們看到有個easing屬性,該屬性傳的是動畫執行的曲線速度,可以自己實現,在Easing API中已經有多種不同的效果。大家可以自己去看看實現,源碼地址是 https://github.com/facebook/react-native/blob/master/Libraries/Animated/src/Easing.js ,自己實現的話直接給一個計算函數就可以,可以自己去看模仿。

定義顯示時間

在前面我們設置Toast顯示1000ms,我們對顯示時間進行自定義,限定類型number,

time: PropTypes.number

在構造方法中對時間的處理

time: props.time && props.time < 1500 ? Toast.SHORT : Toast.LONG,

在此處我對時間顯示處理為SHORT和LONG兩種值了,當然你可以自己處理為想要的效果。

然后只需要修改timingDismiss中的時間1000,寫為this.state.time就可以了。

組件更新

當組件已經存在時再次更新屬性時,我們需要對此進行處理,更新state中的message和time,并清除定時器,重新定時。

componentWillReceiveProps(nextProps) {   this.setState({      message: nextProps.message !== undefined ? nextProps.message : '',      time: nextProps.time && nextProps.time < 1500 ? Toast.SHORT : Toast.LONG,    })    clearTimeout(this.dismissHandler)    this.timingDismiss()  }

組件注冊

為了我們的定義的組件以API的形式調用,而不是寫在render方法中,所以我們定義一個跟組件

import React, {Component} from "react";import {StyleSheet, AppRegistry, View, Text} from 'react-native';viewRoot = null;class RootView extends Component {  constructor(props) {    super(props);    console.log("constructor:setToast")    viewRoot = this;    this.state = {      view: null,    }  }  render() {    console.log("RootView");    return (<View style={styles.rootView} pointerEvents="box-none">      {this.state.view}    </View>)  }  static setView = (view) => {//此處不能使用this.setState    viewRoot.setState({view: view})  };}const originRegister = AppRegistry.registerComponent;AppRegistry.registerComponent = (appKey, component) => {  return originRegister(appKey, function () {    const OriginAppComponent = component();    return class extends Component {      render() {        return (          <View style={styles.container}>            <OriginAppComponent/>            <RootView/>          </View>        );      };    };  });};const styles = StyleSheet.create({  container: {    flex: 1,    position: 'relative',  },  rootView: {    position: "absolute",    left: 0,    right: 0,    top: 0,    bottom: 0,    flexDirection: "row",    justifyContent: "center",  }});export default RootView

RootView就是我們定義的根組件,實現如上,通過AppRegistry.registerComponent注冊。

包裝供外部調用

import React, {  Component,} from 'react';import RootView from '../RootView'import ToastView from './ToastView'class Toast {  static LONG = 2000;  static SHORT = 1000;  static show(msg) {    RootView.setView(<ToastView      message={msg}      onDismiss={() => {        RootView.setView()      }}/>)  }  static show(msg, time) {    RootView.setView(<ToastView      message={msg}      time={time}      onDismiss={() => {        RootView.setView()      }}/>)  }}export default Toast

Toast中定義兩個static變量,表示顯示的時間供外部使用。然后提供兩個static方法,方法中調用RootView的setView方法將ToastView設置到根view。

使用

首先導入上面的Toast,然后通過下面方法調用

Toast.show("測試,我是Toast");          //能設置顯示時間的Toast          Toast.show("測試",Toast.LONG);

好了文章介紹完畢。如果想看完整代碼,可以進我 GitHub 查看。文中若有不足或錯誤的地方歡迎指出。希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。最后新年快樂。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宝坻区| 十堰市| 当阳市| 儋州市| 临泽县| 芜湖县| 长海县| 防城港市| 洛浦县| 武定县| 黎川县| 亳州市| 吕梁市| 湛江市| 潮安县| 夏河县| 乌兰浩特市| 德江县| 舒城县| 天柱县| 静海县| 沛县| 兴业县| 托克逊县| 灌云县| 德惠市| 界首市| 包头市| 冀州市| 北宁市| 昌平区| 雅江县| 招远市| 准格尔旗| 甘德县| 浦县| 宜宾市| 宜宾市| 固始县| 彰武县| 吉隆县|