小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
1.背景
无论是移动开发还是Web开发中,布局技术都是UI的基础。无论有没有前端的开发经验,相信大家都听过著名的CSS盒子模型。
盒子模型基于position、浮动属性等进行布局,但是对于一些比较特殊但是常用的布局就比较困难,如垂直居中。
于是, 在2009年, W3C提出了一种新的方案一-Flexbox布局。Flexbox(FlexibleBox 的缩写,又称弹性盒子布局〉布局旨在提供一个更加有效的方式制定 、调整和分布一个容 器里的项目布局,即使他们的大小是未知或者动态的。 Flexbox 布局的主要思想是让容器 有能力让其子项目 能够改变其宽度、 高度(甚至顺序),以最佳方式填充可用空间 (主要 是为 了适应所有类型 的显示设备和屏幕大小) 。
React Native实现了Flexbox的大部分的功能,这使得React Native的UI布局更加简单,并且更容易适配iOS、Android的屏幕。
2.属性介绍
Flexbox布局简单概括包括两种:
- 指定子空间排列规则的属性,如flexDirection、flexWrap、justifyContent和alignItems等
- 指定自身的显示属性,如algnSelf和flex等
2.1 flexDirection设置排列方式
flexDirection可指定子控件的排列方向,取值包括:column(默认值)、row和row-reverse。
示例:
const flexStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray'
},view1: {
width: 100,
height: 100,
backgroundColor: 'red'
},
view2: {
width: 100,
height: 100,
backgroundColor: 'green'
}
})
const MyApp = () => {
return (
<View style={flexStyles.container}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
);
}
export default MyApp;
效果如下:
默认采用的是column的方式排列,如果更换为row时,代码如下:
const flexStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
flexDirection: 'row'\改为row
},view1: {
width: 100,
height: 100,
backgroundColor: 'red'
},
view2: {
width: 100,
height: 100,
backgroundColor: 'green'
}
})
...
效果如下:
最后时row-revere,效果时前后反序排列,这个就不写了,大家自己试一下吧。
2.2 flexWrap设置换行
flexWrap表示当子View超出父View时是否进行换行,取值包括:nowrap(默认值)、wrap和wrap-reverse,示例:
const flexStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
flexDirection: 'row',
},view1: {
width: 300,
height: 300,
backgroundColor: 'red'
},
view2: {
width: 300,
height: 300,
backgroundColor: 'green'
}
})
const MyApp = () => {
return (
<View style={flexStyles.container}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
);
}
export default MyApp;
效果如下:
默认为超出时依然按原有布局展示,view2只有部分可正常展示,当flexWrap设置为wrap时,代码如下:
const flexStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
flexDirection: 'row',
flexWrap: 'wrap'\修改为wrap
},view1: {
width: 300,
height: 300,
backgroundColor: 'red'
},
view2: {
width: 300,
height: 300,
backgroundColor: 'green'
}
})
...
效果如下:
当子View超出父View范围后,会自动换行显示
2.3 justifyContent设置横向排列位置
justifyContent 指定子View横向排列在其父View的哪个位置,取值有 flex-start、 flex-end、 center、 space-between 以及 space-around。 示例:
const flexStyles = StyleSheet.create({
container: {
flexDirection: 'row',
backgroundColor: 'gray',
justifyContent: 'flex-start'
},container2: {
flexDirection: 'row',
backgroundColor: 'gray',
justifyContent: 'flex-end'
},container3: {
flexDirection: 'row',
backgroundColor: 'gray',
justifyContent: 'center'
},container4: {
flexDirection: 'row',
backgroundColor: 'gray',
justifyContent: 'space-between'
},container5: {
flexDirection: 'row',
backgroundColor: 'gray',
justifyContent: 'space-around'
},view1: {
width: 100,
height: 100,
backgroundColor: 'red'
},
view2: {
width: 100,
height: 100,
backgroundColor: 'green'
}
})
const MyApp = () => {
return (
<View>
<View style={flexStyles.container}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
<Text>flex-start</Text>
<View style={flexStyles.container2}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
<Text>flex-end</Text>
<View style={flexStyles.container3}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
<Text>center</Text>
<View style={flexStyles.container4}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
<Text>space-between</Text>
<View style={flexStyles.container5}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
<Text>space-around</Text>
</View>
);
}
export default MyApp;
效果图:
2.4 alignItems设置纵向排列位置
alignItems与justifyContent相似,只是alignItems设置的是子View纵向排列的位置。取值包括:flex-start、flex-end、center、baseLine和stretch,示例:
const flexStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
flexDirection: 'row',
alignItems: 'center'
},view1: {
width: 100,
height: 100,
backgroundColor: 'red'
},
view2: {
width: 100,
height: 100,
backgroundColor: 'green'
}
})
const MyApp = () => {
return (
<View style={flexStyles.container}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
);
}
export default MyApp;
效果如下:
基于alignItems和justifyContent可以很轻易的实现屏幕居中:
const flexStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
},view1: {
width: 100,
height: 100,
backgroundColor: 'red'
},
view2: {
width: 100,
height: 100,
backgroundColor: 'green'
}
})
效果:
2.5 alignSelf设置特定View的排列
alignSelf可以设置当前View自身的排列情况,取值包括:auto、flex-start、flex-end、center和stretch。以居中为例:
const flexStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
flexDirection: 'column'
},view1: {
width: 100,
height: 100,
backgroundColor: 'red'
},
view2: {
width: 100,
height: 100,
backgroundColor: 'green',
alignSelf: 'center'
}
})
const MyApp = () => {
return (
<View style={flexStyles.container}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
);
}
export default MyApp;
效果如下:
2.6 flex设置View所占空间
flex可以让组件动态计算和设置自身所占用的空间大小,如果想让view1和view2填满父View,并且view1和view2大小相同,如下:
const flexStyles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'gray',
flexDirection: 'column'
},view1: {
flex: 1,
backgroundColor: 'red'
},
view2: {
flex: 1,
backgroundColor: 'green'
}
})
const MyApp = () => {
return (
<View style={flexStyles.container}>
<View style={flexStyles.view1}/>
<View style={flexStyles.view2}/>
</View>
);
}
export default MyApp;
效果如下:
3.总结
本章主要介绍了React Native中的Flexbox模型,包括:flexDirection、flexWrap、justifyContent、alignItems、alignSelf和flex等属性,相信基于本章的内容,我们可以熟悉使用rn来实现简单的页面布局。