目標
基礎知識的學習只有在實踐中使用才更容易被理解與吸收,前面幾節都是在介紹基本的屬性概念,我自己是一個比較健忘的人,我估計很多人也跟我一樣在學了基本概念后過不了多久就忘了,或者只是有個印象卻不知道該怎么用該在何處運用這些特性。
本節我們將運用前面所介紹的基本概念,進行布局實戰,實現如下效果:
在此之前先介紹一下幾個常見的網格布局。
網格布局
網格布局示例的完整代碼在:
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
加上 flexDirection
和justifyContent
屬性,并添加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
樣式分別加上banner
、category
、recommend
,其中banner
和category
為固定高度,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