React-Native:用JavaScript開發你的原生應用,釋放Native的UI體驗,體驗 Hybird開發效率。css
最近一個星期寫的文章以下,連接是github page的,其實也能夠在系列博客找到相應文章:html
還有幾篇會時刻更新:react
第四篇React-Native佈局實戰(二)ios
在不斷深刻的過程當中,發現React-Native佈局和樣式的坑還有不少,他沒有像瀏覽器那樣靈活和有規律可循,其中的規律須要我本身踩坑的時候發現。好比:不存在zIndex,後面的元素覆蓋前面的元素;內層元素覆蓋外層元素等等,borderRadius的設置,須要考慮到內層元素的位置等等。
這裏選用攜程的App首頁做爲栗子,隨不是嚴格的9宮格(比9宮格稍微難點...),可是能夠很好的讓咱們練習flexbox.最後須要完成的結果以下:
整個頁面咱們能夠分爲幾個部分,大體以下:
由於,組件尚未講,這裏只是作一個簡單的介紹。在React-Native中實現頭部導航欄很簡單,只要使用NavigatorIOS組件便可。如今開工。 一、咱們在index.ios.js中添加以下代碼;同時建立文件夾pagaes和pages下建立Index.js var React = require('react-native'); var Index = require('./pages/Index'); var { NavigatorIOS, AppRegistry, StyleSheet, } = React; var NV = React.createClass({ render: function(){ return( <NavigatorIOS style={styles.container} initialRoute={{ title: '首頁', component: Index, }} /> ); } }); var styles = StyleSheet.create({ container: { flex: 1, } }); AppRegistry.registerComponent('HelloWorld', () => NV); 分析代碼: (1)require:引入外部模塊,就像,引入咱們本身建立的/pages/Index.js同樣。 (2)引入定義NavigatorIOS、AppRegistry、StyleSheet組件和類。 (3)在render中調用NavigatorIOS組件,initialRoute是初始化路由,title是當前頁面的頭部標題;component是當前路由下顯示的組件; (4)注意:這裏NavigatorIOS的style須要設置大小,好比這裏設置是flex:1,不然就不能顯示內容主體; (5)最後咱們須要註冊當前應用:AppRegistry.registerComponent('HelloWorld', () => NV); 二、建立Index.js文件,文件的內容以下, module.exports就暴露了Index模塊。
效果以下圖:git
這裏圖片輪播使用的是第三方組件react-native-swiper,固然React-Native是支持transform能夠直接實現一套。咱們啓動npm命令行,在項目的根目錄使用以下命令安裝模塊。 $ npm react-native-swiper --save 安裝完成後,咱們須要完成輪播功能。由於能夠到github看看swiper暴露的接口和參數。github地址是:https://github.com/leecade/react-native-swiper (1)引入swiper,前面也提到了require. var Swiper = require('react-native-swiper'); (2)使用swiper,將輪播圖封裝成單獨的組件 var sliderImgs = [ 'http://images3.c-ctrip.com/SBU/apph5/201505/16/app_home_ad16_640_128.png', 'http://images3.c-ctrip.com/rk/apph5/C1/201505/app_home_ad49_640_128.png', 'http://images3.c-ctrip.com/rk/apph5/D1/201506/app_home_ad05_640_128.jpg' ]; var Slider = React.createClass({ render: function(){ return ( <Swiper style={styles.wrapper} showsButtons={false} autoplay={true} height={150} showsPagination={false}> <Image style={[styles.slide,]} source={{uri: sliderImgs[0]}}></Image> <Image style={[styles.slide,]} source={{uri: sliderImgs[1]}}></Image> <Image style={[styles.slide,]} source={{uri: sliderImgs[2]}}></Image> </Swiper> ); } }); (3)這樣咱們能夠直接在render的時候直接用:<Slider/>
其實4個九宮格都是同樣,這個其實能夠封裝成組件,這裏採用拷貝的形式,開發一個,其餘3個就ok的,不會偷懶的工程師,不是好工程師[偷笑]。分析下佈局: (1)其實首先是3個列在一行的佈局,那麼外層組件是須要flexDirection: 'row',各佔據寬度的1/3,即各自flex:1; (2)每一個列內又分兩行, 須要每一個行都是flex:1,各佔據高度的一半; (3)第一列是文字圖片組合,其他都是文字組合; (4)全部行內元素都是水平、垂直居中; (5)這裏使用了個TouchableHighlight組件,是爲了出發onPress事件,相似於click或者touch事件。 <View style={[styles.sbu_red, styles.sbu_view]}> <TouchableHighlight underlayColor={'#FA6778'} style={{flex:1}}> <View style={[styles.sbu_flex, styles.sbu_borderRight]}> <View style={[styles.sub_con_flex, styles.sub_text]}> <Text style={[styles.font16]}>酒店</Text> </View> <View style={[styles.sub_con_flex]}> <Image style={[styles.sbu_icon_img]} source={{uri:BUIcon[0]}}></Image> </View> </View> </TouchableHighlight> <View style={[styles.sbu_flex, styles.sbu_borderRight]}> <View style={[styles.sub_con_flex, styles.sub_text, styles.sbu_borderBottom]}> <Text style={[styles.font16]}>海外</Text> </View> <View style={[styles.sub_con_flex, styles.sub_text]}> <Text style={[styles.font16]}>周邊</Text> </View> </View> <View style={[styles.sbu_flex]}> <View style={[styles.sub_con_flex, styles.sub_text, styles.sbu_borderBottom]}> <Text style={[styles.font16]}>團購.特惠</Text> </View> <View style={[styles.sub_con_flex, styles.sub_text]}> <Text style={[styles.font16]}>客棧.公寓</Text> </View> </View> </View>
說完了佈局的原理,這裏須要貼上樣式僅供參考: var styles = StyleSheet.create({ //container container:{ backgroundColor:'#F2F2F2', flex:1, }, //slider wrapper: { height:80, }, slide: { height:80, resizeMode: Image.resizeMode.contain, }, //sbu sbu_view:{ height:84, marginLeft: 5, marginRight:5, borderWidth:1, borderRadius:5, marginBottom:10, flexDirection:'row', }, sbu_red:{ backgroundColor: '#FA6778', borderColor:'#FA6778', marginTop:-70, }, sbu_blue:{ backgroundColor: '#3D98FF', borderColor:'#3D98FF', }, sbu_green:{ backgroundColor: '#5EBE00', borderColor:'#5EBE00', }, sbu_yellow:{ backgroundColor: '#FC9720', borderColor:'#FC9720', }, sbu_flex:{ flex:1, }, sbu_borderRight:{ borderColor:'#fff', borderRightWidth: 0.5, }, sbu_icon_img:{ height:40, width:40, resizeMode:Image.resizeMode.contain, }, sub_con_flex:{ flex:1, justifyContent: 'center', alignItems: 'center', }, sub_text:{ justifyContent:'center', }, font16:{ fontSize:17, color:'#FFF', fontWeight:'900', }, sbu_borderBottom:{ borderBottomWidth:0.5, borderBottomColor:'#fff', }, img_view:{ height:62, marginLeft:5, marginRight:5, flexDirection: 'row', marginBottom:20, backgroundColor:'#fff', }, img_flex:{ flex:1, borderWidth:1, borderColor:'#ccc', }, img_wh: { height:59, borderRightWidth:0, resizeMode:Image.resizeMode.contain, } }); 着重說下resizeMode:Image.resizeMode.contain。在React-Native中圖片的大小是不會根據給定一個寬度或者高度而自適應大小的,所以咱們須要讓圖片根據寬度或者高度來自適應,那麼可使用resizeMode:Image.resizeMode.contain。facebook提示錯誤信息的樣式表中也沒有說起,文檔中也沒有說起。因此後續還有很多的坑須要你們去一塊兒探索。
實例代碼中會涉及ScrollView組件,主要是爲了適應小屏的機器,能夠滾動視圖。
代碼連接:githubgithub