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

转载请标明出处:
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个栏目,每个栏目平分屏幕宽度,在每个栏目的第二和第三列平分栏目的高度形成上下两栏菜单。

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

  1. 水平排列
  2. 设定高度
  3. 距离屏幕左右边以及上边的距离
  4. 圆角
  5. 背景色

编写栏目的样式:

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布局的使用》

©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师:上身试试 返回首页