一起学ReactNative(2) Flex布局入坑手册

    xiaoxiao2021-04-13  24

    前言

    网上面 关于Flex布局的文章 很多 有些也非常的详细 但是我觉得 学东西 还是得从实践触发 而不是光讲理论对不 今天来跟大家分享一下 自己在学习Flex布局中遇到的各种坑 如文章中有任何的错误 都可以直接联系我本人 或者在github上面提交问题 QQ:469373256

    源码地址

    https://github.com/fangkyi02/Demo

    案例1(文本居中)

    错误

    import React, { Component } from 'react'; import { View, Text, StyleSheet, } from 'react-native'; export default class TextAlign extends Component { render() { return ( <View style={styles.container}> <Text style={{justifyContent:'center',alignItems:'center'}}>asdasd</Text> </View> ); } } 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 ( <View style={[styles.container,{justifyContent:'center',alignItems:'center'}]}> <Text >asdasd</Text> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, }, });

    我想刚接触的人 一定有很多人这样尝试过吧 认为 我想实现一个Text那我就应该在Text这个style里面去做修改 但是实际结果却并非如此

    其实Flex布局 你可以这样理解 对于改变控件布局形态的 都得写在父控件里面 比如居中 限宽 限高 对于改变自身子组件的样子 比如背景色 前景色 宽度 高度 等等的 都应该在子控件自身去完成

    这样简单的分类一下 有没有清楚点呢? 看了上面的Text以后 你会发现 我并没有给我的Text限制宽高 但是的确是居中了 那么我们能否给View也尝试这样实现呢?来看一下接下来的案例

    案例2(视图居中)

    错误

    import React, { Component } from 'react'; import { View, Text, StyleSheet, } from 'react-native'; export default class ViewAlign extends Component { render() { return ( <View style={styles.container}> <View style={{backgroundColor:'red'}}></View> </View> ); } } 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里面去实现这个效果

    再看源码之前 先自己脑补一下 应该如何实现 当然 如果你有更好的方式 也可以告诉我

    案例3(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

    转载请注明原文地址: https://ju.6miu.com/read-669034.html

    最新回复(0)