React Native布局

react native目录结构解析

工图初始结构如下:


图片1.png
  • android:一个完整的,集成react native的android studio工程,用android studio打开运行可以跑到手机或者模拟器上。
  • ios:一个完整的ios项目,在Mac下可以直接用xcode打开。运行到模拟器或者手机上
  • node_moules:基于node文件依赖系统产生的相关依赖和第三方lib,里面有react native的大部分组件
  • watchmanconfig:Watchman的配置文件,Watchman用于监控文件变化
  • flowconfig:flow的配置文件,flow用于静态代码检查
  • buckconfig:buck的配置文件,buck是Facebook开源的高效编译系统
  • App.js:Android和iOS的应用程序入口
  • package.json:项目基本信息以及依赖信息
  • index.js :app的注入

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 {
    // 初始化方法 ---> viewDidLoad ---> 返回具体的组件内容
    // 写结构和内容
    render() {
        // 返回一个View
        return (
            
                这是第一次运行成功
                To get started, edit App.js
                {instructions}
            
        );
    }
}

// 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:

  
                这是第一次运行成功
                To get started, edit App.js
                {instructions}
            

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

View组件用法

React Native组件View,其作用等同于iOS中的UIView, Android中的android.view,或是网页中的

标签,它是所有组件的父组件。下面是具体的用法和需要注意的事项:

// 在下面写注释,必须要 {/*  xxxxx  */}这么写
export default class App extends Component{
    render() {
        return (
            
                {/*  View组件中必须有东西才可以显示 */}
                
                    我是里面的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的排列
  • 在CSS中,常规的布局是基于块和内联流方向,而Flex布局是基于flex-flow流,下图很好解释了Flex布局的思想:
图片3.png

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

  • 根据伸缩项目排列方式的不同,主轴和侧轴方向也有所变化:
图片4.png
FlexBox常用属性
容器属性
  • flexDirection: row | row-reverse | column | column-reverse

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

图片5.png
export default class App extends Component{
    render() {
        return (
            
                {/*  View组件中必须有东西才可以显示 */}
                
                    我是里面的View
                
                
                    我是中间的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
    }
});
  • justifyContent:flex-start | flex-end | center | space-between | space-around

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

图片6.png
  • alignItems: flex-start | flex-end | center | baseline | stretch

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

图片7.png
  • flexWrap: nowrap | wrap | wrap-reverse
    默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
    nowrap(默认值):不换行。
    图片8.png

    wrap:换行,第一行在上方。
    图片.png

    wrap-reverse:换行,第一行在下方。(和wrap相反)
    图片.png
元素属性
  • flex
    “flex-grow”、“flex-shrink”和“flex-basis”三个属性的缩写, 其中第二个和第三个参数(flex-shrink、flex-basis)是可选参数。
    默认值为“0 1 auto”。
    宽度 = 弹性宽度 * ( flexGrow / sum( flexGorw ) )
    类似Android中的权重
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
    }
});

  • align-self属性
    align-self属性允许单个项目有与其他项目不一样的侧轴对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
    其值除auto外,其他与align-items完全一致。


    图片9.png

获取屏幕相关参数

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

class CFlexBoxDemo3 extends Component {
  render() {
    return (
        
           当前屏幕的宽度:{Dimensions.get('window').width}
           当前屏幕的高度:{Dimensions.get('window').height}
           当前屏幕的分辨率:{Dimensions.get('window').scale}
        
    );
  }
};

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


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
                
                {/*  垂直居中 */}
                
                    我是中间的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进行判断。

你可能感兴趣的:(React Native布局)