您的位置:首页 > 移动开发

React-Native之仿携程App首页布局

2017-05-28 17:14 489 查看
转载请标明出处:

http://blog.csdn.net/hai_qing_xu_kong/article/details/72793846

本文出自:【顾林海的博客】

前言

本篇介绍React-Native中的View、Text和Image组件的使用,并利用这三个组件编写一个简单的菜单,如果大家看过《React Native入门实战》这本书的话,在这本书的第三章开篇就有这个例子,但是大家如果使用的是React Native最新版本 0.44,会发现书中的例子根本跑不通,因此本篇文章的例子基于最新版本0.44,重新改写了这个例子,并在原有的基础上补充完整。好了我们先来看看这个九宫格菜单的效果:



属性讲解

从效果图中可以看出上面菜单分为3个栏目,每个栏目平分屏幕宽度,在每个栏目的第二和第三列平分栏目的高度形成上下两栏菜单。

由于这三个栏目的样式是一样的,所以我们只要画出其中一个就可以了,每一栏的特点如下:

水平排列

设定高度

距离屏幕左右边以及上边的距离

圆角

背景色

编写栏目的样式:

const styles=StyleSheet.create({
containertop:{
marginTop:15,
marginLeft:5,
marginRight:5,
height:84,
flexDirection:'row',
borderRadius:5,
backgroundColor:'#FF0067',
}

});


marginTop距离上方15pt,marginLeft距离左边5pt,marginRight距离右边5pt,height用于设置组件的高度,flexDirection:’row’ 代表了组件的排列方式,属性row表示横向排列,column表示纵向排列,默认是column,borderRadius代表圆角为5,并且设置了背景色为‘#FF0067‘。

接着编写栏目的视图,这里用到View、Text组件,因此需要我们加载这两个组件:

import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
} from 'react-native';

export default class ReactDeomo01 extends Component {
render(){
return(
<View style={styles.containertop}>

</View>
);
}
}

const styles=StyleSheet.create({ containertop:{ marginTop:15, marginLeft:5, marginRight:5, height:84, flexDirection:'row', borderRadius:5, backgroundColor:'#FF0067', } });

AppRegistry.registerComponent('ReactDeomo01', () => ReactDeomo01);


运行效果如下:



横向的菜单设置如下:

平分屏幕剩余宽度

文字大小

文字颜色

居中

修改代码如下:

import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
PixelRatio
} from 'react-native';

export default class ReactDeomo01 extends Component {
render(){
return(
<View style={styles.flex}>
<View style={styles.containertop}>
<View style={[styles.item,styles.center]}>
<Text style={styles.font}>item1</Text>
</View>
<View style={[styles.item,styles.center]}>
<Text style={styles.font}>item2</Text>
</View>
<View style={[styles.item,styles.center]}>
<Text style={styles.font}>item3</Text>
</View>
</View>

</View>
);
}
}

const styles=StyleSheet.create({
containertop:{
marginTop:15,
marginLeft:5,
marginRight:5,
height:84,
flexDirection:'row',
borderRadius:5,

backgroundColor:'#FF0067',
},
item:{
flex:1,
height:80,
},
center:{
justifyContent:'center',
alignItems:'center'
},
flex:{
flex:1
},
font:{
color:'#fff',
fontSize:16,

}
});

AppRegistry.registerComponent('ReactDeomo01', () => ReactDeomo01);


由于内部3个View组件是水平布局的,View组件的flex属性设置为1,所以平分屏幕宽度,内部View组件height高度设置80,justifyContent设置为center在交叉轴的中间,alignItems设置为center水平居中,最里面是Text组件,设置了color颜色为’#fff’,文字fontSize大小为16,fontWeight设置为粗体。

运行效果如下:



接下来添加线条,这里引入PixelRatio API,PixelRatio的get方法用于获取设备的像素比,这里1/PixelRatio.get()获取最小线宽。

新增样式如下:

lineLeftRight:{
borderLeftWidth:1/PixelRatio.get(),
borderRightWidth:1/PixelRatio.get(),
borderColor:'#fff'
},


borderLeftWidth是左边框的宽度,borderRightWidth是右边框的宽度,线宽颜色borderColor为’#fff’

修改代码如下:

export default class ReactDeomo01 extends Component {
render(){
return(
<View style={styles.flex}>
<View style={styles.containertop}>
<View style={[styles.item,styles.center]}>
<Text style={styles.font}>item1</Text>
</View>
<View style={[styles.item,styles.center,styles.lineLeftRight]}>
<Text style={styles.font}>item2</Text>
</View>
<View style={[styles.item,styles.center]}>
<Text style={styles.font}>item3</Text>
</View>
</View>

</View>
);
}
}


运行效果如下:



Image组件用于显示图片,加载方式分为两种,本地和网络加载。

本地加载:

<Image source={require('./img/plane-icon.png')} style={styles.image}/>


./img/plane-icon.png表示同级目录下的img目录下的plane-icon.png图片。

网络加载:

<Image source={{uri: 'http://cdn8.staztic.com/app/i/5140/5140559/comgotohzhztourapp-1-l-124x124.png'}} style={styles.image}/>


这里图片轮播使用的是第三方组件react-native-swiper,当然React-Native是支持transform可以直接实现一套。我们启动npm命令行,在项目的根目录使用如下命令安装模块。

$ npm install react-native-swiper --save
$ npm i react-timer-mixin --save


到这里相关的属性讲解完毕,最后做的就是将这些组件拼接在一起,下面是完整的源码:

import React, { Component } from 'react';

var Swiper = require('react-native-swiper');

import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
PixelRatio,
ScrollView,
} from 'react-native';

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 imageUrl = [
'https://raw.githubusercontent.com/vczero/vczero.github.io/master/ctrip/%E6%9C%AA%E6%A0%87%E9%A2%98-1.png',
'https://raw.githubusercontent.com/vczero/vczero.github.io/master/ctrip/feiji.png',
'https://raw.githubusercontent.com/vczero/vczero.github.io/master/ctrip/lvyou.png',
];

var Slider = React.createClass({
render: function(){
return (
<Swiper style={styles.wrapper} showsButtons={false} autoplay={true} height={80} 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>
);
}
});

export default class ReactDeomo01 extends Component {

render(){
return(
<ScrollView>
<View style={{flex:1}}>
<Slider/>
<View style={styles.flex}>
<View style={[styles.containertop,styles.sbu_red,styles.topradius]}>
<View style={[styles.item,styles.center]}>
<Text style={styles.font}>酒店</Text>
<Image source={{uri: imageUrl[0]}} style={styles.image}/>
</View>
<View style={[styles.item,styles.lineLeftRight]}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>海外酒店</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>特价酒店</Text>
</View>
</View>
<View style={styles.item}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>团购</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>名宿·短租</Text>
</View>
</View>
</View>

<View style={[styles.containermiddle,styles.sbu_blue]}>
<View style={[styles.item,styles.center]}>
<Text style={styles.font}>机票</Text>
<Image source={{uri: imageUrl[1]}} style={styles.image}/>
</View>
<View style={[styles.item,styles.lineLeftRight]}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>火车票</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>特价机票</Text>
</View>
</View>
<View style={styles.item}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>汽车票·船票</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>专车·租车</Text>
</View>
</View>
</View>

<View style={[styles.containermiddle,styles.sbu_green]}>
<View style={[styles.item,styles.center]}>
<Text style={styles.font}>旅游</Text>
<Image source={{uri: imageUrl[2]}} style={styles.image}/>
</View>
<View style={[styles.item,styles.lineLeftRight]}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>目的地攻略</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>周边游</Text>
</View>
</View>
<View style={styles.item}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>邮轮旅行</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>定制旅行</Text>
</View>
</View>
</View>

<View style={[styles.containermiddle,styles.sbu_yellow,styles.bottomradius]}>
<View style={styles.item}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>景点·玩乐</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>礼品卡</Text>
</View>
</View>
<View style={[styles.item,styles.lineLeftRight]}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>美食林</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>WiFi·电话卡</Text>
</View>
</View>
<View style={styles.item}>
<View style={[styles.center,styles.flex,styles.lineCenter]}>
<Text style={styles.font}>购物·外汇</Text>
</View>
<View style={[styles.center,styles.flex]}>
<Text style={styles.font}>保险·签证</Text>
</View>
</View>
</View>

<View style={[styles.secondmenu]}>
<View style={[{flexDirection:'row'},styles.menulineCenter]}>
<View style={[styles.item,styles.center,styles.menulineRight]}>
<Image source={require('./img/icon1.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>自由行</Text>
</View>
<View style={[styles.item,styles.center,styles.menulineRight]}>
<Image source={require('./img/icon2.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>微领队</Text>
</View>
<View style={[styles.item,styles.center,styles.menulineRight]}>
<Image source={require('./img/icon3.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>一日游</Text>
</View>
<View style={[styles.item,styles.center]}>
<Image source={require('./img/icon4.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>高端游</Text>
</View>
</View>
<View style={[{flexDirection:'row'},styles.menulineCenter]}>
<View style={[styles.item,styles.center,styles.menulineRight]}>
<Image source={require('./img/icon4.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>酒店+景点</Text>
</View>
<View style={[styles.item,styles.center,styles.menulineRight]}>
<Image source={require('./img/icon3.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>海外玩乐</Text>
</View>
<View style={[styles.item,styles.center,styles.menulineRight]}>
<Image source={require('./img/icon2.png')}style={styles.secondimage}/>
<Text style={styles.secondfont}>寄存·托运</Text>
</View>
<View style={[styles.item,styles.center]}>
<Image source={require('./img/icon1.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>加盟合作</Text>
</View>
</View>
<View style={{flexDirection:'row'}}>
<View style={[styles.item,styles.center,styles.menulineRight]}>
<Image source={require('./img/icon1.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>外币兑换</Text>
</View>
<View style={[styles.item,styles.center,styles.menulineRight]}>
<Image source={require('./img/icon2.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>当季去哪</Text>
</View>
<View style={[styles.item,styles.center,styles.menulineRight]}>
<Image source={require('./img/icon3.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>机场停车</Text>
</View>
<View style={[styles.item,styles.center]}>
<Image source={require('./img/icon4.png')} style={styles.secondimage}/>
<Text style={styles.secondfont}>更多服务</Text>
</View>
</View>
</View>

<View style={{height:30}}></View>

</View>

</View>

</ScrollView>
);
}
}

const styles=StyleSheet.create({

sbu_red:{
backgroundColor: '#FA6778',
borderColor:'#FA6778',
},

sbu_blue:{
backgroundColor: '#3D98FF',
borderColor:'#3D98FF',
},

sbu_green:{
backgroundColor: '#5EBE00',
borderColor:'#5EBE00',
},

sbu_yellow:{
backgroundColor: '#FC9720',
borderColor:'#FC9720',
},
containertop:{
marginTop:5,
marginLeft:5,
marginRight:5,
height:84,
flexDirection:'row',
padding:2,
},
topradius:{
borderTopLeftRadius:5,
borderTopRightRadius:5
},
bottomradius:{
borderBottomLeftRadius:5,
borderBottomRightRadius:5
},
containermiddle:{
marginTop:5,
marginLeft:5,
marginRight:5,
height:84,
flexDirection:'row',
padding:2,
backgroundColor:'#FF0067',
},
secondmenu:{
marginTop:5,
marginLeft:5,
marginRight:5,
backgroundColor:'white'
},
item:{
flex:1,
height:80,
},
center:{
justifyContent:'center',
alignItems:'center'
},
flex:{
flex:1
},
font:{
color:'#fff',
fontSize:14,
},
secondfont:{
color:'black',
fontSize:10,
},
lineLeftRight:{
borderLeftWidth:1/PixelRatio.get(),
borderRightWidth:1/PixelRatio.get(),
borderColor:'#fff'
},

lineCenter:{
borderBottomWidth:1/PixelRatio.get(),
borderColor:'#fff'
},
menulineRight:{
borderRightWidth:0.5/PixelRatio.get(),
borderColor:'#d0d0d0'
},

menulineCenter:{
borderBottomWidth:1/PixelRatio.get(),
borderColor:'#d0d0d0'
},
image:{
width:30,
height:30,
marginTop:5
},
secondimage:{
width:20,
height:20,
marginBottom:4
},
wrapper: {
height:80,
},
slide: {
height:80,
resizeMode: Image.resizeMode.contain,
},

});

AppRegistry.registerComponent('ReactDeomo01', () => ReactDeomo01);


注意:这里图片是在同级img目录下,没有这个目录请创建这个目录,最后要记得往里面添加照片!!!

关于React Native的布局请查看《 React-Native中的flexbox布局的使用》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: