网上面 关于Flex布局的文章 很多 有些也非常的详细 但是我觉得 学东西 还是得从实践触发 而不是光讲理论对不 今天来跟大家分享一下 自己在学习Flex布局中遇到的各种坑 如文章中有任何的错误 都可以直接联系我本人 或者在github上面提交问题 QQ:469373256
https://github.com/fangkyi02/Demo
我想刚接触的人 一定有很多人这样尝试过吧 认为 我想实现一个Text那我就应该在Text这个style里面去做修改 但是实际结果却并非如此
其实Flex布局 你可以这样理解 对于改变控件布局形态的 都得写在父控件里面 比如居中 限宽 限高 对于改变自身子组件的样子 比如背景色 前景色 宽度 高度 等等的 都应该在子控件自身去完成
这样简单的分类一下 有没有清楚点呢? 看了上面的Text以后 你会发现 我并没有给我的Text限制宽高 但是的确是居中了 那么我们能否给View也尝试这样实现呢?来看一下接下来的案例
这个代码 是为了实现一个红色的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控件 <View style={styles.itemView}> {/* item主体内容 */} <View> <Text>{el.text}</Text> </View> </View> ); }) }这里做一下解释 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控件 <View style={styles.itemView}> {/* item主体内容 */} <View> <TouchableOpacity onPress={this._itemDown.bind(this,i)}> <Text style={this.state.id==i?styles.itemTextFocus:styles.itemTextNoFocus}>{el.text}</Text> </TouchableOpacity> </View> </View> ); }) }这里也很简单 根据this.state.id的值然后判断需要采取哪个styles 然后当你按下的时候 触发onPress的时候 然后设置你的state.id为i值 这个时候因为setState的关系 会导致整个页面刷新 然后又回到了刚才的判断this.state.id那边 来进行刷新渲染
记得 如果要使用这个方法来实现的话 最好将tab封装成一个子组件 不然像我这样直接进行setState会导致 下面的视图组件也进行重新的渲染
好了 来看一下结果吧
我的所有源码都已经上传到了github 你们有兴趣的话 可以自己去做修改 比如实现下面的滑块条效果 https://github.com/fangkyi02/Demo 如项目中有什么错误的地方 还望大家指正 QQ:469373256