React Native移動框架功能研究react
此篇只研究React Native框架的功能。android
1、React Natvie是什麼ios
React Native是使用React(或者說JS)來開發原生APP的框架。git
2、React Native的願景github
1.提供一直的跨平臺開發原生APP的一直體驗。spring
2.使用JS和React提升跨平臺開發效率。react-native
3、React Native提供的特性數組
1.提供了豐富的原生組件,能夠是APP得到平臺一致的視覺效果和體驗,同時得到最佳的性能和流暢性。babel
// iOS & Android var React = require('react-native'); var { ScrollView, TouchableHighlight, Text } = React; var TouchDemo = React.createClass({ render: function() { return ( <ScrollView> <TouchableHighlight onPress={() => console.log('pressed')}> <Text>Proper Touch Handling</Text> </TouchableHighlight> </ScrollView> ); }, });
2.JS代碼和原平生臺之間的全部操做都是異步執行的,原生模塊能夠根據須要自由建立線程。同時二者之間的通信是徹底可序列化的,這使其能夠藉助Chorme開發這工具進行調試。網絡
3.提供強大的觸控事件處理系統,能夠在複雜的UI層次結構下方便的處理觸控事件。
// iOS & Android var React = require('react-native'); var { ScrollView, TouchableHighlight, Text } = React; var TouchDemo = React.createClass({ render: function() { return ( <ScrollView> <TouchableHighlight onPress={() => console.log('pressed')}> <Text>Proper Touch Handling</Text> </TouchableHighlight> </ScrollView> ); }, });
4.經過Flexbox簡化UI佈局,提供高性能機制聲明樣式和佈局,並可直接應用到組件中。
// iOS & Android var React = require('react-native'); var { Image, StyleSheet, Text, View } = React; var ReactNative = React.createClass({ render: function() { return ( <View style={styles.row}> <Image source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}} style={styles.image} /> <View style={styles.text}> <Text style={styles.title}> React Native </Text> <Text style={styles.subtitle}> Build high quality mobile apps using React </Text> </View> </View> ); }, }); var styles = StyleSheet.create({ row: { flexDirection: 'row', margin: 40 }, image: { width: 40, height: 40, marginRight: 10 }, text: { flex: 1, justifyContent: 'center'}, title: { fontSize: 11, fontWeight: 'bold' }, subtitle: { fontSize: 10 }, });
5.提供靈活的機制,方便自定義原生視圖和模塊。4、React Native的功能1.樣式React Native在JS中定義和引用樣式。能夠經過StyleSheet定義樣式
var styles = StyleSheet.create({ base: { width: 38, height: 38, }, background: { backgroundColor: '#222222', }, active: { borderWidth: 2, borderColor: '#00ff00', }, });
在組件中使用樣式
<Text style={styles.base} /> <View style={styles.background} />
同時能夠接受多個樣式,後邊的會覆蓋前邊的樣式
<View style={[styles.base, styles.background]} />
能夠結合表達式控制是否應用樣式
<View style={[styles.base, this.state.active && styles.active]} />
也能夠直接在元素中聲明樣式,可是每次渲染都會重建樣式,影響性能。
<View style={[styles.base, { width: this.state.width, height: this.state.width * this.state.aspectRatio }]} />
樣式也能夠做爲參數傳遞
var List = React.createClass({ propTypes: { style: View.propTypes.style, elementStyle: View.propTypes.style, }, render: function() { return ( <View style={this.props.style}> {elements.map((element) => <View style={[styles.element, this.props.elementStyle]} /> )} </View> ); } }); // ... 在別的文件中引用List組件 ... <List style={styles.list} elementStyle={styles.listElement} />
2.圖片加載本地靜態圖片,圖片基於當前js的目錄。若是帶有平臺相關的擴展名,則系統自動根據當前的系統平臺自動加載相關的圖片,例如my-icon.ios.png
<Image source={require('./my-icon.png')} />
使用@2x,@3x這樣的文件名後綴,能夠爲不一樣的屏幕精度提供圖片能夠在React Native中直接使用內嵌到APP中的圖片資源
<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />
能夠加載網絡圖片,可是須要手動指定圖片大小
<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
style={{width: 400, height: 400}} />
經過將元素嵌套到Image中實現背景圖片
return ( <Image source={...}> <Text>Inside</Text> </Image> );
3.手勢觸控系統提供Touchable和TouchableHighlight來定義可觸控控件。響應者的聲明週期以下:是否願意成爲響應者View.props.onStartShouldSetResponder(開始觸摸的時候是否願意)View.props.onMoveShouldSetResponder(若是不是響應者,則每次開始移動觸控點時詢問是否緣由)若是願意成爲響應者,則接下來開始嘗試成爲響應者View.props.onResponderGrant(成功成爲響應者)View.props.onResponderReject(被拒絕成爲響應者)若是成功成爲響應者,則開始具體的響應觸控事件View.props.onResponderMove(響應屏幕手指移動)View.props.onResponderRelease(響應屏幕手指離開)View.props.onResponderTerminationRequest(其餘組件請求接替響應者,返回true則釋放本身響應者角色)View.props.onResponderTerminate(響應者角色已交出)onStartShouldSetResponder與onMoveShouldSetResponder是以冒泡的形式調用的,即嵌套最深的節點最早調用。若是某個父View會但願能先成爲響應者。咱們能夠利用「捕獲期」來解決這一需求。View.props.onStartShouldSetResponderCaptureView.props.onMoveShouldSetResponderCapture4.動畫用於全局的佈局動畫LayoutAnimation,和用於建立更精細的交互控制的動畫Animated。Animated庫使得開發者能夠很是容易地實現各類各樣的動畫和交互方式,而且具有極高的性能。它包括兩個值類型,Value用於單個的值,而ValueXY用於向量值;還包括三種動畫類型,spring,decay,還有timing,以及三種組件類型,View,Text和Image。咱們可使用Animated.createAnimatedComponent方法來對其它類型的組件建立動畫。
class Playground extends React.Component { constructor(props: any) { super(props); this.state = { bounceValue: new Animated.Value(0), }; } render(): ReactElement { return ( <Animated.Image // 可選的基本組件類型: Image, Text, View source={{uri: 'http://i.imgur.com/XMKOH81.jpg'}} style={{ flex: 1, transform: [ // `transform`是一個有序數組(動畫按順序執行) {scale: this.state.bounceValue}, // 將`bounceValue`賦值給 `scale` ] }} /> ); } componentDidMount() { this.state.bounceValue.setValue(1.5); // 設置一個較大的初始值 Animated.spring( // 可選的基本動畫類型: spring, decay, timing this.state.bounceValue, // 將`bounceValue`值動畫化 { toValue: 0.8, // 將其值以動畫的形式改到一個較小值 friction: 1, // Bouncier spring } ).start(); // 開始執行動畫 } }
多個動畫能夠經過parallel(同時執行)、sequence(順序執行)、stagger和delay來組合使用。
Animated.sequence([ // 首先執行decay動畫,結束後同時執行spring和twirl動畫 Animated.decay(position, { // 滑行一段距離後中止 velocity: {x: gestureState.vx, y: gestureState.vy}, // 根據用戶的手勢設置速度 deceleration: 0.997, }), Animated.parallel([ // 在decay以後並行執行: Animated.spring(position, { toValue: {x: 0, y: 0} // 返回到起始點開始 }), Animated.timing(twirl, { // 同時開始旋轉 toValue: 360, }), ]), ]).start();
LayoutAnimation容許在全局範圍內建立和更新動畫,它經常使用來更新flexbox佈局。
var App = React.createClass({ componentWillMount() { // 建立動畫 LayoutAnimation.spring(); }, getInitialState() { return { w: 100, h: 100 } }, _onPress() { // 讓視圖的尺寸變化以動畫形式展示 LayoutAnimation.spring(); this.setState({w: this.state.w + 15, h: this.state.h + 15}) }, render: function() { return ( <View style={styles.container}> <View style={[styles.box, {width: this.state.w, height: this.state.h}]} /> <TouchableOpacity onPress={this._onPress}> <View style={styles.button}> <Text style={styles.buttonText}>Press me!</Text> </View> </TouchableOpacity> </View> ); } });
若是對性能要求比較高,setNativeProps方法可使咱們直接修改基於原生視圖的組件的屬性,而不須要使用setState來從新渲染整個組件樹,從而可使咱們得到較好的性能。此時應該注意被render從新調用的時候覆蓋掉。5.提供的調試工具開發者菜單Chrome開發者工具React開發工具插件FPS監視器6.自動化測試使用Jest進行單元測試,使用Travis做爲持續集成系統。集成測試和快照測試只使用IOS。7.JS環境在IOS、Android模擬器和真機上,使用的是JavaScriptCore。在Chorme調試時,代碼運行在V8引擎中。React Native從0.5.0版本開始已經內置Babel轉換器,使咱們可使用最新的js語法編寫代碼。8.導航器官方提供提供通用跨平臺的Navigator,js編寫方便擴展。開源社區提供的NavigatorIOS,只能在IOS中使用,依賴Object-c,積壓bug無人解決,不建議使用。9.特定平臺代碼將代碼放在特定平臺的文件夾下/common/components/ /android/components//ios/components/組件命名中添加平臺標誌BigButtonIOS.jsBigButtonAndroid.js特定平臺擴展名BigButton.ios.jsBigButton.android.js在js中判斷當前平臺
var {Platform} = React; var styles = StyleSheet.create({ height: (Platform.OS === 'ios') ? 200 : 100, });
五、已知存在的問題模塊和原生視圖缺失,好比Maps、Spinner等
某些屬性僅僅支持單個平臺
有一些已經存在的組件和
API
沒能進行統一抽象爲通用的
,好比
ActivityIndicatorIOS
和
ProgressBarAndroid
overflow
樣式在
Android
中沒法使用
不支持
Android M
(
6.0
)的權限
NG
圖片的內存問題