ReactNative

React Native布局

2019-01-04  本文已影响2人  DramaScript

react native目录结构解析

工图初始结构如下:


图片1.png

App.js内容解析

App.js

App.js作为整个程序入口,里面的代码含义相当于Android的

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

//引入 React的抽象组件
import React, {Component} from 'react';
// 引入React具体的组件,比如image,text等
import {AppRegistry, Platform, StyleSheet, Text, View} from 'react-native';
import {name as appName} from "./app";

// 下面根据平台的api展示不同的文字
const instructions = Platform.select({
    ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
    android:
        'Double tap R on your keyboard to reload,\n' +
        'Shake or press menu button for dev menu',
});

type Props = {};
// 这个class 最终是在index.js中调用了AppRegistry.registerComponent(appName, () => App);注入了才得以显示,类似android的setContentView()
export default class App extends Component<Props> {
    // 初始化方法 ---> viewDidLoad ---> 返回具体的组件内容
    // 写结构和内容
    render() {
        // 返回一个View
        return (
            <View style={styles.container}>
                <Text style={styles.welcome}>这是第一次运行成功</Text>
                <Text style={styles.instructions}>To get started, edit App.js</Text>
                <Text style={styles.instructions}>{instructions}</Text>
            </View>
        );
    }
}

// View组件的样式
const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
    },
    instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
    },
});

index.js文件:

/** @format */

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

// App 这个在App.js中定义,等同于之前版本的AppRegistry.registerComponent('untitled1', () => App);
AppRegistry.registerComponent(appName, () => App);

组件View

JSX的由来

React的核心机制之一就是虚拟DOM:可以在内存中创建的虚拟DOM元素。React利用虚拟DOM来减少对实际DOM的操作从而提升性能。传统的创建方式是:


图片2.png

但这样的代码可读性并不好,于是React发明了JSX,利用我们熟悉的HTML语法来创建虚拟DOM:

  <View style={styles.container}>
                <Text style={styles.welcome}>这是第一次运行成功</Text>
                <Text style={styles.instructions}>To get started, edit App.js</Text>
                <Text style={styles.instructions}>{instructions}</Text>
            </View>

在实际开发中,JSX在产品打包阶段都已经编译成纯JavaScript,JSX的语法不会带来任何性能影响。因此,JSX本身并不是什么高深的技术,可以说只是一个比较高级但很直观的语法糖。

View组件用法

React Native组件View,其作用等同于iOS中的UIView, Android中的android.view,或是网页中的<div>标签,它是所有组件的父组件。下面是具体的用法和需要注意的事项:

// 在下面写注释,必须要 {/*  xxxxx  */}这么写
export default class App extends Component{
    render() {
        return (
            <View style={styles.container}>
                {/*  View组件中必须有东西才可以显示 */}
                <View style={styles.innerViewStyle}>
                    <Text>我是里面的View</Text>
                </View>
                <View style={styles.innerViewStyle2}>
                    <Text>我是里面下面的View</Text>
                </View>
            </View>
        );
    }
}

//  在React Native开发中,更加推荐我们采用StyleSheet来进行组件的布局,这样的话,代码在结构上会更加的清晰、也有利于后期维护。
const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#ffffff',
        padding: 30
    },
    innerViewStyle:{
        backgroundColor:'green',
        width:100
    },
    innerViewStyle2:{
        backgroundColor:'yellow',
        width:100
    }
});

FlexBox布局

在Android中我们有许多的布局,比如线性布局,相对布局等,在react native中FlexBox布局是用的最频繁的,含义是能够伸缩或者很容易变化,以适应外界条件的变化的通用的矩形容器。简称“弹性布局”,旨在通过弹性的方式来对齐和分布容器中内容的空间,使其能适应不同屏幕,为盒装模型提供最大的灵活性。说了那么多就是集合Android线性布局和相对布局等其他布局的一些特征的布局。

Flexbox的排列
图片3.png

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。项目默认沿主轴排列,单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

图片4.png
FlexBox常用属性
容器属性

该属性决定主轴的方向(即项目的排列方向)。
row:主轴为水平方向,起点在左端。
row-reverse:主轴为水平方向,起点在右端。
column(默认值):主轴为垂直方向,起点在上沿。
column-reverse:主轴为垂直方向,起点在下沿。

图片5.png
export default class App extends Component{
    render() {
        return (
            <View style={styles.container}>
                {/*  View组件中必须有东西才可以显示 */}
                <View style={styles.innerViewStyle}>
                    <Text>我是里面的View</Text>
                </View>
                <View style={styles.innerViewStyle2}>
                    <Text>我是中间的View</Text>
                </View>
                <View style={styles.innerViewStyle3}>
                    <Text>我是里面下面的View</Text>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#ffffff',
        padding: 30,
        flexDirection: 'row'  // 横向
    },
    innerViewStyle:{
        backgroundColor:'green',
        width:100
    },
    innerViewStyle2:{
        backgroundColor:'yellow',
        width:100
    },
    innerViewStyle3:{
        backgroundColor:'red',
        width:100
    }
});

定义了伸缩项目在主轴线的对齐方式
flex-start(默认值):伸缩项目向一行的起始位置靠齐。
flex-end:伸缩项目向一行的结束位置靠齐。
center:伸缩项目向一行的中间位置靠齐。
space-between:两端对齐,项目之间的间隔都相等。
space-around:伸缩项目会平均地分布在行里,两端保留一半的空间

图片6.png

定义项目在交叉轴上如何对齐,可以把其想像成侧轴(垂直于主轴)的“对齐方式”。
flex-start:交叉轴的起点对齐。
flex-end:交叉轴的终点对齐 。
center:交叉轴的中点对齐。
baseline:项目的第一行文字的基线对齐。
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

图片7.png
元素属性
const styles = StyleSheet.create({
    container: {
        backgroundColor: '#ffffff',
        padding: 30,
        flexDirection: 'row',  // 横向
        justifyContent: 'flex-start',
        alignItems: 'center',
    },
    innerViewStyle:{
        backgroundColor:'green',
        flex: 1
    },
    innerViewStyle2:{
        backgroundColor:'yellow',
        flex: 1
    },
    innerViewStyle3:{
        backgroundColor:'red',
        flex: 1
    }
});

获取屏幕相关参数

获取当前屏幕的宽度、高度、分辨率
// 引入
var Dimensions = require('Dimensions');
var {width, height, scale} = Dimensions.get('window');

class CFlexBoxDemo3 extends Component {
  render() {
    return (
        <View style={styles3.outViewStyle}>
           <Text>当前屏幕的宽度:{Dimensions.get('window').width}</Text>
           <Text>当前屏幕的高度:{Dimensions.get('window').height}</Text>
           <Text>当前屏幕的分辨率:{Dimensions.get('window').scale}</Text>
        </View>
    );
  }
};

const styles3 = StyleSheet.create({
  outViewStyle:{
    // 占满屏幕
    flex:1,
    //  主轴方向居中
    justifyContent:'center',
    // 侧轴方向居中
    alignItems: 'center',
    // 背景
    backgroundColor:'red'
  }
});
绝对定位和相对定位
class CFlexBoxDemo4 extends Component {
    render() {
        return (
            <View style={styles4.outViewStyle}>
                <Text>绝对定位</Text>
                <View style={styles4.topViewStyle}>
                    <View style={styles4.innerViewStyle}></View>
                </View>
                <Text>相对定位</Text>
                <View style={styles4.topViewStyle}>
                    <View style={styles4.innerViewStyle1}></View>
                </View>
            </View>
        );
    }
};


const styles4 = StyleSheet.create({
    outViewStyle:{
        marginTop:20,
        width:width,
        height:200,
        backgroundColor:'red'
    },

    topViewStyle:{
        width:width,
        height:150,
        backgroundColor:'yellow'
    },

    innerViewStyle:{
        width:60,
        height:60,
        backgroundColor:'green',
        // 绝对定位
        position:'absolute',
        top:0,
        right:0
    },

    innerViewStyle1:{
        width:60,
        height:60,
        backgroundColor:'green',
        // 相对定位
        position:'relative',
        top:30,
        right:-30
    }
});

通常情况下设置position和absolute,定位的效果是一样的,但是如果父组件设置了内边距,position会做出相应的定位改变,而absolute则不会。flex的元素如果不设置宽度, 都会百分之百的占满父容器。

export default class App extends Component {
    render() {
        return (
            <View style={styles.container}>
                {/*  水平居中 */}
                <View style={{height:100,  alignItems: 'center'}}>
                    <Text style={styles.innerViewStyle}>我是里面的View</Text>
                </View>
                {/*  垂直居中 */}
                <View style={{height:100,  justifyContent: 'center'}}>
                    <Text style={styles.innerViewStyle2}>我是中间的View</Text>
                </View>
                {/*  水平垂直居中 */}
                <View style={{height:100,  alignItems: 'center', justifyContent: 'center',backgroundColor:'black'}}>
                    <Text style={styles.innerViewStyle3}>我是里面下面的View</Text>
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        backgroundColor: '#ffffff',
    },
    innerViewStyle: {
        backgroundColor: 'green',
        height: 30,
        width: 100,

    },
    innerViewStyle2: {
        backgroundColor: 'yellow',
        height: 30,
        width: 100,

    },
    innerViewStyle3: {
        backgroundColor: 'red',
        height: 30,
        width: 100,
    }
});
图片.png

注意:一旦设置alignItems属性之后,组件的大小包裹随着内容的尺寸;此外水平居中和垂直居中还要结合FlexDirection进行判断。

上一篇 下一篇

猜你喜欢

热点阅读