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來)掛起全部還沒有執行的任務。