Alert - 弹窗html
经过 Alert.alert() 方法调用唤起原生弹窗,点击会触发 onPress 回调(参考下方代码)并清除弹窗。node
import React, { AppRegistry, Component, StyleSheet, Alert, Text, View } from 'react-native'; class AwesomeProject extends Component { componentDidMount(){ Alert.alert( 'Alert标题', '一些正文内容', [ //{text: '稍后询问', onPress: () => console.log('Ask me later pressed')}, //{text: '取消', onPress: () => console.log('Cancel Pressed')}, {text: 'OK', onPress: () => console.log('OK Pressed')} ] ) } render() { return ( <View style={styles.container}> <Text style={styles.text}> DEMO </Text> </View> ); } }
按钮数量将决定其排版(下图),不一样于ios,安卓没法定义按钮样式:react
(单个按钮状况)ios
(两个按钮状况)git
(三个按钮状况)github
Animated - 动画接口web
篇幅较大,故独立写了两篇文章:json
ReactNative入门 —— 动画篇(上)react-native
AppRegistry - APP注册接口
最经常使用的接口,特别是 AppRegistry.registerComponent 方法,用于注册根组件到当前APP,进而让原生系统加载时能够执行对应的bundle文件:
AppRegistry.registerComponent('AppName', () => RootComponent);
除了 registerComponent 以外,还提供了其它一些比较少用的接口:
registerConfig(config<Array>) //注册配置 registerRunnable(appKey<String>, func<Function>) //注册函数监听 getAppKeys() //获取registerRunnable注册的监听键 runApplication(appKey<String>, appParams<any>) //运行App
AppState - 应用状态
经过此接口能够获悉应用在当前处于后台仍是前台激活的状态,经常使用方法和应用场景相似于h5的visibilitychange。
注意该接口要最新版本(2.0+)的 react-native 才能调用。
获取到的应用状态常规有:
active:表示应用处于前台运行状态;
background:表示应用处于后台挂起状态;
inactive:过渡状态,常规不会发生,能够先忽略该状态。
咱们可使用 AppState.addEventListener 和 AppState.removeEventListener 方法来监听、移除应用状态的 change 事件。
另外也能够直接使用 AppState.currentState 来得到应用当前的状态:
import React, { AppRegistry, Component, StyleSheet, Alert, AppState, Text, View } from 'react-native'; class AwesomeProject extends Component { componentDidMount() { AppState.addEventListener('change', this._handleAppStateChange); //组件挂载时获取当前状态 Alert.alert('当前状态', AppState.currentState, [{text: 'OK'}]); } componentWillUnmount() { AppState.removeEventListener('change', this._handleAppStateChange); } _handleAppStateChange(currentAppState) { currentAppState==='active' && Alert.alert('状态转变', currentAppState, [{text: 'OK'}]) } render() { return ( <View style={styles.container}> <Text style={styles.text}> DEMO </Text> </View> ); } }
注:若是在模拟器中出现“screenPhysicalPixels undefined”的问题,试着执行 react-native upgrade 来更新gradle(见此issue)
AsyncStorage - 异步存储
相似于 localStorage,经常使用于本地存储一些键值对类型的数据,这些存储的数据对应整个应用自己而已经是全局性质的(相似 localStorage 在同个域下共享)。
其对外方法主要有:
getItem(key<String>, [callback<Function(error, result)>]) 获取单个数据,返回一个 Promise 对象 setItem(key<String>, [callback<Function(error)>]) 设置单个数据,返回一个 Promise 对象 removeItem(key<String>, [callback<Function(error)>]) 移除单个数据,返回一个 Promise 对象 mergeItem(key<String>, value<String>, [callback<Function(error)>]) 合并某个已存在的数据项,一般该项为stringified json格式。该接口返回一个 Promise 对象 clear([callback<Function(error)>]) 清除所有 AsyncStorage 数据,返回一个 Promise 对象 getAllKeys(callback<Function(error, keys)>) 获取全部键,返回一个 Promise 对象 flushGetRequests() 清空全部进行中的查询 multiGet(keys<Array>, [callback<Function(error, keys)>]) 获取多项,查询 keys(字符串数组)指定的多个键来查询对应的值。该接口返回一个 Promise 对象 multiGet(keys<Array>, [callback<Function(error, keyValuePairs)>]) 获取多项,参数 keys 是一个字符串数组,回调里的形参 keyValuePairs 是字符串的二维数组,表示最终得到的键值对组。该接口返回一个 Promise 对象 multiSet(keyValuePairs<Array>, [callback<Function(error, keys)>]) 设置多项,参数 keyValuePairs 是字符串的二维数组。该接口返回一个 Promise 对象 multiRemove(keys<Array>, [callback<Function(error)>]) 移除 keys(字符串数组)指定的多项。返回一个 Promise 对象 multiMerge(keyValuePairs<Array>, [callback<Function(error)>]) 合并多项已有的键值对,参数 keyValuePairs 是字符串的二维数组。该接口返回一个 Promise 对象。注意该接口还不完善,未能被全部原生支持。
先来看一个简单的 AsyncStorage 数据设置与获取:
import React, { AppRegistry, Component, StyleSheet, Alert, AsyncStorage, Text, View } from 'react-native'; class AwesomeProject extends Component { constructor(props) { super(props); this.state = { time : '123' }; } componentDidMount() { AsyncStorage.setItem('timeStamp', Date.now() + '', function(err){ //错误处理 err && console.log(err) }).done(function(){ Alert.alert( '恭喜', '数据设置成功', [ {text: 'OK', onPress: () => {}} ] ) }) } _getData() { AsyncStorage.getItem('timeStamp', function(err, data){ if(err) return console.log(err); this.setState({ time : data }) }.bind(this)); } render() { return ( <View style={styles.container}> <Text style={styles.text}> {this.state.time || '暂无数据'} </Text> <View style={styles.btnWrap}> <Text style={styles.btn} onPress={this._getData.bind(this)}>点我获取</Text> </View> </View> ); } }
再来一个 multiSet 和 multiGet 的示例:
class AwesomeProject extends Component { constructor(props) { super(props); this.state = { a : '' }; } componentDidMount() { var me = this; AsyncStorage.multiSet([['a','1'], ['b','2']], function(err){ if(err) return console.log(err); AsyncStorage.multiGet(['a', 'b'], function(err, keyValuePairs) { keyValuePairs.forEach(function (keyValuePair) { if (keyValuePair[0] === 'a') { me.setState({ a: keyValuePair[1] }) } }); }) }) } _mergeData() { var me = this; AsyncStorage.multiSet([['a','5'], ['c','2']], function(err){ if(err) return console.log(err); AsyncStorage.getItem('a', function(err, value) { me.setState({ a: value }) }) }) } render() { return ( <View style={styles.container}> <Text style={styles.text}> {this.state.a || '加载中'} </Text> <View style={styles.btnWrap}> <Text style={styles.btn} onPress={this._mergeData.bind(this)}>点我合并</Text> </View> <View style={styles.btnWrap}> <Text style={styles.btn} onPress={AsyncStorage.getItem.bind(this, ['0',{}])}>点我reload</Text> </View> </View> ); } }
注意 multiMerge 接口还不能被全部原生环境支持,调用的时候极可能会直接报错。事实上能够直接用 multiSet 替代。
BackAndroid - 返回处理
能够经过该接口来处理应用返回事件。
经过 BackAndroid.addEventListener 和 BackAndroid.removeEventListener 事件,能够监听/移除用户点击安卓设备系统返回键的事件。
经过 BackAndroid.exitApp() 方法能够直接退出当前应用:
class AwesomeProject extends Component { constructor(props) { super(props); this.state = { a : '' }; } componentDidMount() { BackAndroid.addEventListener('hardwareBackPress', this._handleBackPressed.bind(this)); } componentWillUnmount() { BackAndroid.removeEventListener('change', this._handleBackPressed.bind(this)); } _handleBackPressed() { this.setState({ a : 'backPressed' }) } _exitApp() { BackAndroid.exitApp() } render() { return ( <View style={styles.container}> <Text style={styles.text}> {this.state.a || '加载中'} </Text> <View style={styles.btnWrap}> <Text style={styles.btn} onPress={this._exitApp.bind(this)}>退出应用</Text> </View> </View> ); } }
效果1——点击系统返回键:
效果2——调用 exitApp 方法:
CameraRoll - 相册接口
与相册交互的接口,然而安卓这块没IOS的支持好用(没法保存非本地图片)。
1. 经过 CameraRoll.saveImageWithTag(uri) 能够保存某张本地图片到相册,其中 uri 必须为本地地址(例如 'file:///sdcard/img.png')。
该接口返回一个 Promise 对象(成功时的回调参数为图片存储后的图片ID):
_handleSavePic() { var me = this; CameraRoll.saveImageWithTag('file:///sdcard/img.png').done(function(uri){ me.setState({ a : uri }) }, function(err){ Alert.alert( '保存失败', JSON.stringify(err), [ {text: 'OK'} ] ) }) }
2. 经过 CameraRoll.getPhotos(params<Object>) 能够从相册里去获取图片,其中 params 参数格式为:
{ first : 3, //获取图片的个数 groupTypes : React.propTypes.oneOf([ //分组类型 'Album', 'All', 'Event', 'Faces', 'Library', 'PhotoStream', 'savePhotos' ]), assetType : React.propTypes.oneOf([ //资源类型 'Photos', 'All', 'Videos' ]) }
该接口返回一个 Promise 对象,成功的回调参数数据格式为:
{ edges: [{ node: { timestamp: 1405312098, group_name: 'CameraRoll', type: 'ALAssetTypePhoto', image: { isStored: true, height: 669, uri: 'asset-library: //asset/assert.JPG?id=C9DB366F-350876C78006&ext=JPG', width: 1008 } }, {node: ....} }], page_info: { has_next_page: true, start_cursor: 'asset-library: //asset/assert.JPG?id=C9DB366F-350876C78006&ext=JPG', end_cursor: 'asset-library...' } } //参考至“ReactNative入门与实战”一书162页
来个简单示例:
_handleGetImages() { var me = this; var params = { first : 3, groupTypes : 'Album', assetType : 'Photos' }; CameraRoll.getPhotos(params).done(function(data){ var edges = data.edges, photos = []; edges.forEach(function(edge){ photos.push(edge.node.image.uri) }); me.setState({ photos: photos }) }, function(err){ Alert.alert( '打开相册失败', JSON.stringify(err), [ {text: 'OK'} ] ) }) }
Clipboard - 剪切板
该模块接口具备获取/设置剪切板内容的能力。
经过 Clipboard.getString() 能够得到设备剪切板内容,经过 Clipboard.setString(content<String>) 能够设置剪切板内容:
class AwesomeProject extends Component { constructor(props) { super(props); } _onPress(){ Clipboard.setString('你好啊') } render() { return ( <View style={styles.container}> <TouchableOpacity> <View style={[styles.button,{backgroundColor:'#CCC'}]}> <TextInput /> </View> </TouchableOpacity> <TouchableOpacity onPress={this._onPress}> <View style={styles.button}> <Text style={styles.buttonText}>修改剪切板内容为“你好啊”</Text> </View> </TouchableOpacity> </View> ); } }
DatePickerAndroid - 日期选择器
经过 DatePickerAndroid.open(options<Object>) 方法能够打开一个标准的Android时间选择器的对话框,并返回一个Promise对象。
其中 options 参数参考以下:
date (Date对象或毫秒时间戳) - 默认显示的日期 minDate (Date对象或毫秒时间戳) - 可选的最小日期 maxDate (Date对象或毫秒时间戳) - 可选的最大日期
Promise的回调参数为:
action - 对应动做,若为取消对话框,该值为 DatePickerAndroid.dismissedAction year - 选中的年份,若为取消对话框,该值为undefined month (0-11) - 选中的月份,若为取消对话框,该值为undefined day - 选中的天值,若为取消对话框,该值为undefined
所以咱们能够经过判断 Promise 回调中的 action 是否等价于 DatePickerAndroid.dismissedAction,来得知用户是否作了取消对话框的行为:
class AwesomeProject extends Component { constructor(props) { super(props); } _onPress(){ DatePickerAndroid.open({ date: new Date(), minDate: new Date('1900/01/01'), maxDate: new Date('2100/12/12') }).done(function(params){ var content = ''; if(params.action !== DatePickerAndroid.dismissedAction){ content = '你选中了' + params.year + '年' + (params.month+1) + '月' + params.day + '日' } else { content = '你退出了时间选择对话框' } Alert.alert( '时间选择结果', content, [ {text: 'OK', onPress: () => console.log('OK Pressed')} ] ) }) } render() { return ( <View style={styles.container}> <TouchableOpacity onPress={this._onPress}> <View style={styles.button}> <Text style={styles.buttonText}>打开日期选择器</Text> </View> </TouchableOpacity> <TouchableOpacity> <View style={styles.button}> <Text style={styles.buttonText}>somebtn</Text> </View> </TouchableOpacity> </View> ); } }
Dimensions - 获取应用窗口尺寸
可经过 Dimensions.get('window') 来获取当前窗口尺寸,获得一个含有 width 和 height 属性的对象。
经常使用于设置图片宽高(例如设置图片宽度为屏幕宽度):
import React, { AppRegistry, Component, StyleSheet, Dimensions, Text, View } from 'react-native'; class AwesomeProject extends Component { constructor(props) { super(props); this.state = { width : '', height : '' }; } componentDidMount() { var win_info = Dimensions.get('window'); this.setState({ width: win_info.width, height: win_info.height }) } render() { return ( <View style={styles.container}> <Text style={styles.text}> 屏幕宽度:{this.state.width || '加载中'} </Text> <Text style={styles.text}> 屏幕高度:{this.state.height || '加载中'} </Text> </View> ); } }
启动后显示效果以下:
InteractionManager - 交互管理器
在web页面,咱们常规会使用 setImmediate/setTimeout/requestAnimationFrame 来定义动画下一帧的执行时间点,在 RN 的动画交互中,咱们经过使用 InteractionManager.runAfterInteractions() 来作对应处理是最佳的选择。
例如咱们但愿安卓切换场景的时候,能在场景切换动画结束了才开始执行某些操做,能够这么写:
componentDidMount: function(){ InteractionManager.runAfterInteractions(() => { //TODO: some events }); }
另外咱们能够经过 createInteractionHandle() 接口建立一个交互句柄,通知系统当前有个动画交互开始了。
动画结束时再经过 clearInteractionHandle(handle) 来通知系统该动画交互已结束。
示例:
var handle = InteractionManager.createInteractionHandle(); // 开始执行某些动画交互... (`runAfterInteractions` 任务会被压入队列中等候动画结束) // 动画交互执行完毕的时候执行clearInteractionHandle通知系统交互结束: InteractionManager.clearInteractionHandle(handle); // 触发runAfterInteractions
另外 InteractionManager 还有一个静态方法 setDeadline(deadline<Number>),用于(使用setTimeout来)挂起全部还没有执行的任务。