react native学习笔记5——布局实战篇

目标

基础知识的学习只有在实践中使用才更容易被理解与吸收,前面几节都是在介绍基本的属性概念,我自己是一个比较健忘的人,我估计很多人也跟我一样在学了基本概念后过不了多久就忘了,或者只是有个印象却不知道该怎么用该在何处运用这些特性。
本节我们将运用前面所介绍的基本概念,进行布局实战,实现如下效果:


在此之前先介绍一下几个常见的网格布局。

网格布局

网格布局示例的完整代码在:
https://github.com/mronion0603/ReactNativeExercise/blob/master/src/02_flex/GridDemo.js

基本的均分网格布局

最简单的网格布局,就是平均分布,在容器里面平均分配空间。
将flex都设为1,或各个子元素flex都设置一个相同的值。

代码示例如下:

<View style={ {flexDirection:'row',height:40}}>
    <View style={ {flex:1,backgroundColor:"grey"}}></View>
    <View style={ {flex:1,backgroundColor:"white"}}></View>
    <View style={ {flex:1,backgroundColor:"grey"}}></View>
</View> 

两边固定中间填充的网格

两边的元素设置固定宽度width:100,中间的元素设置flex:1

一般标题栏可以通过这种方法布局。
代码实现如下:

<View style={ {flexDirection:'row',height:40}}>
    <View style={ {width:100,backgroundColor:"grey"}}></View>
    <View style={ {flex:1,backgroundColor:"white"}}></View>
    <View style={ {width:100,backgroundColor:"grey"}}></View>
</View>

嵌套的网格

要实现一些稍微复杂点的效果,通常一层网格是搞不定的,这时需要网格嵌套网格,一层嵌套一层。如下图所示:

代码实现:

<View style={ {flex:1}}>
    <View style={ {flexDirection:'row',height:40}}>
        <View style={ {width:50,backgroundColor:"grey",justifyContent:"center",alignItems:"center"}}>
            <Text>返回</Text>
        </View>
        <View style={ {flex:1,backgroundColor:"white",justifyContent:"center",alignItems:"center"}}>
            <Text>嵌套网格</Text>
        </View>
        <View style={ {width:50,backgroundColor:"grey",justifyContent:"center",alignItems:"center"}}>
            <Text>确认</Text>
        </View>
    </View>
    <View style={ {flexDirection:'row',flex:1,backgroundColor:"#cccccc",justifyContent:"center",alignItems:"center"}}>
        <Text>do something...</Text>
    </View>
</View>

一个稍微复杂点的界面

下面通过实例运用前面介绍的几个基本网格布局,以及上一篇文章介绍的布局基本知识实现一个稍微复杂点的例子,完成如下效果:

事先声明,示例图中上面的banner和底部的tab都是假的,只是用静态图片代替,因为本文的重点是介绍布局,当然后面会介绍banner以及tabnavigation的使用。

步骤
初看上去界面有点复杂,其实都是由一层层简单的布局嵌套之后形成的,将它们一层层拨开,你心里可能会想也就那么回事。下面来带领大家一步步构建出这样的一个漫画App首页的布局效果。

整个页面的框架

最外层是由一个上下的滑动视图+固定高度的底部导航栏构成。因此该布局可以由主轴为竖直轴(flexDirection: "column"也可以不写,因为默认主轴是竖直轴) 的父容器,子元素上部分是一个ScrollView,底部是一个高度固定的导航栏。

import React, {Component} from 'react';
import {
    Text,
    View,
    ScrollView,
    Image
} from 'react-native';

export default class ComicMainDemo extends Component {
    render() {
        return (
            <View style={styles.container}>
                <ScrollView>
                </ScrollView>
                <View style={styles.foot}>
                </View>
            </View>
        );
    }
}

const styles = {
    container: {
        flex: 1,
        backgroundColor: '#d0d0d0'
    },
    foot: {
        height: 50,
        backgroundColor: '#ffffff',
    },
};

效果图如下:


底部导航栏

底部导航栏有四个图片等分底部,其实这里我们有两个思路:一个是用前面介绍的等分网格,为这四个子元素设置flex:1;另一种方法是给父元素设置justifyContent:'space-around'。这里采用第二种方法。
在前面的<View style={styles.foot}><View>中加入四张图片:

<View style={styles.foot}>
    <Image style={styles.footimage} source={require('../images/home_boy.png')}/>
    <Image style={styles.footimage} source={require('../images/book_boy.png')}/>
    <Image style={styles.footimage} source={require('../images/ground_boy.png')}/>
    <Image style={styles.footimage} source={require('../images/mine_boy.png')}/>
</View>

然后为styles.foot加上 flexDirectionjustifyContent属性,并添加styles.footimage的样式:

foot: {
    height: 50,
    backgroundColor: '#ffffff',
    flexDirection: "row",
    justifyContent: "space-around"
},
footimage: {
    height: 50,
    width: 50
}

效果图如下:

主体内容ScrollView

主体内容可以分为三个模块,上:广告栏区,中:分类按钮区,下:推荐漫画区。在<ScrollView></ScrollView>中加入这三个模块

<ScrollView>
    <View style={styles.banner}>
    </View>
    <View style={styles.category}>
    </View>
    <View style={styles.recommend}>
    </View>
</ScrollView>

style样式分别加上bannercategoryrecommend,其中bannercategory为固定高度,recommend填充剩余空间。

banner: {
    height: 200,
    backgroundColor: '#d0d0d0',
},
category: {
    height: 100,
    backgroundColor: '#ffffff',
    flexDirection: "row",
    justifyContent: "space-around",
    paddingTop: 10,

},
recommend: {
    flex: 1,
    backgroundColor: '#ffffff',
    marginTop: 8,
},

Reload JS,可以看到:

广告栏

广告栏区这里只用一个图片表示,由于本文主要讲解布局,所以就不用banner的组件(后面的文章会介绍用真正的banner做广告栏的),只是用静态图片代替。
<View style={styles.banner}></View>中加入一张广告图片:

<View style={styles.banner}>
     <Image style={styles.bannerimage} source={{uri: 'https://manhua.qpic.cn/operation/0/15_00_20_3ffa389e446f5206e24c82ad5c24fd14_1500049213201.jpg/0'}}/>
</View>

style加上bannerimage的样式:

bannerimage: {
    height: 200,
},

在看看效果:

已经有些雏形了有木有!

分类区

分类区也是五个子元素均分整个区域,类似底部的导航栏,前面介绍导航栏时我说有两种思路,导航栏用了第二种,这里我就用第一种方法吧——均分网格。将每个子元素的flex都设为1。
<View style={styles.category}></View>中加入五个子元素

<View style={styles.category}>
    <View style={styles.categorybox}>
        <Image style={styles.categoryimage} source={require('../images/vip_account.png')}/>
        <Text style={styles.categorytext}>男生榜</Text>
    </View>
    <View style={styles.categorybox}>
        <Image style={styles.categoryimage} source={require('../images/user_crown_is_vip.png')}/>
        <Text style={styles.categorytext}>人气榜</Text>
    </View>
    <View style={styles.categorybox}>
        <Image style={styles.categoryimage} source={require('../images/vip_finish.png')}/>
        <Text style={styles.categorytext}>热卖榜</Text>
    </View>
    <View style={styles.categorybox}>
        <Image style={styles.categoryimage} source={require('../images/vip_cloud.png')}/>
        <Text style={styles.categorytext}>排行榜</Text>
    </View>
    <View style={styles.categorybox}>
        <Image style={styles.categoryimage} source={require('../images/color_for_danmu_select.png')}/>
        <Text style={styles.categorytext}>分类</Text>
    </View>
</View>

加上它们对应的style样式:

categorybox: {
    flex: 1,
    backgroundColor: '#ffffff',
    alignItems: "center"
},
categoryimage: {
    height: 50,
    width: 50,
},
categorytext: {
    alignSelf: 'center',
    fontSize: 12,
    color: '#333333',
},

再次Reload看看效果:

已经越来越是那么回事了!

推荐区

推荐区这里又分为两部分,上方的小标题栏,以及下方的图片展示区。
小标题栏这里我们采用了前面介绍的两边固定中间填充的网格
<View style={styles.recommend}></View>中插入推荐小标题栏:

<View style={styles.recommend}>
    <View style={styles.recommendtitlecontainer}>
        <View style={styles.recommendspaceview}></View>
        <View style={styles.recommendtitle}>
            <Text style={styles.recommendtitletext}>主编推荐</Text>
        </View>
        <View style={styles.recommendspaceview}>
            <Image style={styles.recommendmoreimage} source={require('../images/more_boy.png')}/>
        </View>
    </View>
</View>

相应的style样式:

recommendtitlecontainer: {
    height: 50,
    justifyContent:"center",
    flexDirection:"row"
},
recommendspaceview: {
    justifyContent:"center",
    width:100,
},
recommendtitle: {
    flex:1,
    justifyContent:"center",
},
recommendtitletext: {
    alignSelf: 'center',
    fontSize: 14,
    color: '#333333',
},
recommendmoreimage: {
    height: 35,
    width:80,
    alignSelf: 'center',
},

接下来是最后的图片展示区了,在<View style={styles.recommend}></View>中,在<View style={styles.recommend}></View>下面加入<View style={styles.recommendcomic}></View>

<View style={styles.recommendcomic}>
    <Image style={styles.recommendcomicimage}
           source={{uri: 'https://manhua.qpic.cn/vertical/0/21_14_21_96ed95f31667b3966cb0e0521ce13703_1498026084112.jpg/420'}}/>
    <Image style={styles.recommendcomicimage}
           source={{uri: 'https://manhua.qpic.cn/vertical/0/21_14_21_96ed95f31667b3966cb0e0521ce13703_1498026084112.jpg/420'}}/>
    <Image style={styles.recommendcomicimage}
           source={{uri: 'https://manhua.qpic.cn/vertical/0/21_14_21_96ed95f31667b3966cb0e0521ce13703_1498026084112.jpg/420'}}/>
    <Image style={styles.recommendcomicimage}
           source={{uri: 'https://manhua.qpic.cn/vertical/0/21_14_21_96ed95f31667b3966cb0e0521ce13703_1498026084112.jpg/420'}}/>
    <Image style={styles.recommendcomicimage}
           source={{uri: 'https://manhua.qpic.cn/vertical/0/21_14_21_96ed95f31667b3966cb0e0521ce13703_1498026084112.jpg/420'}}/>
    <Image style={styles.recommendcomicimage}
           source={{uri: 'https://manhua.qpic.cn/vertical/0/21_14_21_96ed95f31667b3966cb0e0521ce13703_1498026084112.jpg/420'}}/>
</View>

最后,我们再在styles对象里给图片展示区添加相应的样式。

recommendcomic: {
    flex: 1,
    backgroundColor: '#ffffff',
    flexDirection: "row",
    justifyContent: "space-around",
    marginTop: 5,
    flexWrap:"wrap",
    paddingBottom:10,
},
recommendcomicimage: {
    height: 160,
    width:140,
    marginTop:10,
},

再来看看最终的效果吧:

是不是有些小小的成就感,当然真正的应用布局远比这个Demo复杂,本文只是提供一个运用前面基础布局知识的思路, 算是抛砖引玉吧。本文中的顶部的广告栏和底部导航栏都只是用了简单的图片替代,并没实现真正的效果。后面我会专门介绍navigation及spanner来实现导航栏和广告栏的。

最后附上本节的完整代码
https://github.com/mronion0603/ReactNativeExercise/blob/master/src/02_flex/ComicMainDemo.js

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,123评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,031评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,723评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,357评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,412评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,760评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,904评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,672评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,118评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,456评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,599评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,264评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,857评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,731评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,956评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,286评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,465评论 2 348

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,742评论 25 707
  • 前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人...
    珍此良辰阅读 7,278评论 33 15
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,734评论 1 92
  • 大家下午好今天那就是课件的相对来说会长一点,那我就不需就不用文字了,我就用语音和大家说说吧。 希望大家就是一定要认...
    刘小清阅读 612评论 0 0
  • 本文参考自Spring官方文档 Spring EL。 在Java上有很多表达式语言,在很多领域有各种各样的应用。我...
    乐百川阅读 11,854评论 0 8