网上面 关于Flex布局的文章 很多 有些也非常的详细
但是我觉得 学东西 还是得从实践触发 而不是光讲理论对不
今天来跟大家分享一下 自己在学习Flex布局中遇到的各种坑
如文章中有任何的错误 都可以直接联系我本人
或者在github上面提交问题
QQ:469373256
https://github.com/fangkyi02/Demo
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
} from 'react-native';
export default class TextAlign extends Component {
render() {
return (
container}>
'center',alignItems:'center'}}>asdasd
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
} from 'react-native';
export default class TextAlign extends Component {
render() {
return (
container,{justifyContent:'center',alignItems:'center'}]}>
asdasd
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
我想刚接触的人 一定有很多人这样尝试过吧 认为 我想实现一个Text那我就应该在Text这个style里面去做修改 但是实际结果却并非如此
其实Flex布局 你可以这样理解
对于改变控件布局形态的 都得写在父控件里面 比如居中 限宽 限高
对于改变自身子组件的样子 比如背景色 前景色 宽度 高度 等等的 都应该在子控件自身去完成
这样简单的分类一下 有没有清楚点呢?
看了上面的Text以后 你会发现 我并没有给我的Text限制宽高 但是的确是居中了 那么我们能否给View也尝试这样实现呢?来看一下接下来的案例
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet,
} from 'react-native';
export default class ViewAlign extends Component {
render() {
return (
container}>
'red'}}>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent:'center',
alignItems:'center'
},
});
这个代码 是为了实现一个红色的View居中的效果 先看看 觉得代码有没有什么问题呢 静思三秒 然后继续往下看
import React, { Component } from ‘react’;
import {
View,
Text,
StyleSheet,
} from ‘react-native’;
export default class ViewAlign extends Component {
render() {
return (
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent:’center’,
alignItems:’center’
},
});
不知道大家 有没有看出区别
为什么第一个不行 第二个加了一个宽高以后就可以了呢 我刚才的Text那边 不也没有写宽高的嘛 为啥就可以显示出来呢
这边跟大家说一下 一个View 你在不给定宽高跟flex的情况下 他是没有大小的一个空视图 所以你在这个时候 虽然给他指定了一个红色的背景 但是他也无法显示出来 哪怕你给他外面指定了一个居中
但是这里就会问了 为什么我刚才的Text没有指定宽高 依旧能显示出来呢
那是因为你的text的内容 就是宽高 你有了文本 有了内容 根据fontSize的这个值 你不就有了宽高了嘛
好 到目前为止 我们已经了解了 文本视图跟视图布局如何进行居中 也从中对于Flex有了一点了解 那么 我们就相对加深一下学习
还是实现居中的效果 不过 我们这次是要在tab里面去实现这个效果
再看源码之前 先自己脑补一下 应该如何实现 当然 如果你有更好的方式 也可以告诉我
首先 我们假设 我们有5个TabItem
所以 我们在这边进行一下数据初始化
我这里随便输几个文字用来做Tab的标题
constructor(props){
super(props);
this.data = [
{text:'首页'},
{text:'附近'},
{text:'好友'},
{text:'我的'},
{text:'内容'},
]
}
好 现在我们已经有了一个标题的数组了 接下来 我们就需要先创建一个tab的控件层
首先 我们要限制一下这个tab容器的高度 因为 你如果接下来要进行居中的话 你总不想看到你的这个tab是铺满整个屏幕的吧
render() {
return (
<View style={styles.container}>
{/* tab容器自身 */}
<View style={styles.tabView}>
{/* tab内容部分 */}
<View style={styles.tabMainView}>
{/* tabItem主体 */}
{this._initRender()}
View>
{/* tab滑动视图 用来处理tab按下以后的滑动 */}
<View style={styles.slide}/>
View>
View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
tabView:{
height:50,
},
tabMainView:{
height:50-3,
flexDirection:'row',
},
slide:{
height:5,
width:width/5,
backgroundColor:'red'
}
});
好 现在 一个tab容器已经呈现出来了 接下来 就是要为每个tab加上内容
_initRender = () =>{
return this.data.map((el,i)=>{
return (
// 单个的item控件
{/* item主体内容 */}
{el.text}
);
})
}
这里做一下解释
el 数组内容
i 数组内容位置
首先map从数组中 依次的枚举出 我在数组中填写的初始化标题数据
然后这个el的数据传递给了text文本 并且通过外部包裹的view变成一个组件视图
但是这里要注意 这里的map中return的数据 并没有立即返回 他是等整个数组循环完成以后 在做了返回
一个简单的tab就这样实现了 当然 这个只是最简单的tab
如果你想实现一些效果的话 可以这样实现 也非常简单
_itemDown = (i) =>{
this.setState({
id:i
});
}
_initRender = () =>{
return this.data.map((el,i)=>{
return (
// 单个的item控件
{/* item主体内容 */}
this ._itemDown.bind(this,i)}>
this .state.id==i?styles.itemTextFocus:styles.itemTextNoFocus}>{el.text}
);
})
}
这里也很简单 根据this.state.id的值然后判断需要采取哪个styles
然后当你按下的时候 触发onPress的时候 然后设置你的state.id为i值
这个时候因为setState的关系 会导致整个页面刷新 然后又回到了刚才的判断this.state.id那边 来进行刷新渲染
记得 如果要使用这个方法来实现的话 最好将tab封装成一个子组件 不然像我这样直接进行setState会导致 下面的视图组件也进行重新的渲染
好了 来看一下结果吧
我的所有源码都已经上传到了github 你们有兴趣的话 可以自己去做修改 比如实现下面的滑块条效果
https://github.com/fangkyi02/Demo
如项目中有什么错误的地方 还望大家指正
QQ:469373256