React Native布局入门

在本教程中,您将学习如何布局React Native应用程序以及如何实现应用程序中常用的布局。 这包括堆栈布局,网格布局和绝对布局。 我假设您已经了解了React Native应用程序样式的基础知识以及一般如何使用CSS,因此我不会过多地关注StyleSheet.create以及如何向不同的元素添加样式。

您可以在GitHub上找到本教程的完整源代码 。

项目设置

为了使事情变得容易,我们将使用React Native for Web 。 借助用于Web Starter的React Native ,我们可以轻松启动可以在浏览器中运行的新React Native项目。 此代码与React Native项目 100%兼容。 我们将为要实现的每个布局创建一个单独的组件,以便您可以根据需要轻松地将它们导入到正常的React Native项目中。 我们只是使用React Native for Web,因为它更容易启动和运行。

您可以执行以下命令来设置项目:

git clone https://github.com/grabcode/react-native-web-starter.git RNLayouts
cd RNLayouts
rm -rf .git
npm install

安装完成后,在app / components目录中导航。 这是我们将主要处理的文件。

打开App.js文件,并用以下内容替换默认代码:

import React, { Component } from 'react';

//import the components that we'll be creating here

export class App extends Component {
  render() {
    return (
        //use the components here
    );
  }
}

稍后,您可以导入我们将要创建的组件,然后从该文件中渲染它们。 只需记住,我们保存在layouts目录中的任何组件都不应使用其他任何元素进行渲染。 例如,如果我们有layouts / StackLayout.js ,请在App.js中执行以下操作

import React, { Component } from 'react';

//import the components that we'll be creating here
import StackLayout from './layouts/StackLayout';

export class App extends Component {
  render() {
    return (
        
    );
  }
}

您可以通过执行以下命令为项目提供服务:

npm run dev

这样,您可以通过访问http://localhost:3000在浏览器中对其进行访问。 如果您更改当前从App.js文件导入的任何文件,将触发整页重新加载。

如何创建不同的布局

React Native中的布局使用Flexbox的子集。 (我说“子集”是因为未包括Flexbox规范中的所有功能。)因此,如果您已经知道Flexbox,则可以轻松地在React Native中应用这些技能。 还值得注意的是,React Native中没有浮点数或基于百分比的单位。 这意味着我们只能使用Flexbox和CSS定位进行布局。

堆叠布局

我们将要实现的第一种布局是堆栈布局。 对于垂直方向,它将元素堆叠在一起,而对于水平方向,则将元素并排放置。 首先让我们看一下垂直方向:

React Native布局入门_第1张图片

这是完成上述布局的代码:

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  Dimensions
} from 'react-native';

var { height } = Dimensions.get('window');

var box_count = 3;
var box_height = height / box_count;

export default class VerticalStackLayout extends Component {
  render() {
    return (
        
            
            
            
        
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column'
  },
  box: {
    height: box_height
  },
  box1: {
    backgroundColor: '#2196F3'
  },
  box2: {
    backgroundColor: '#8BC34A'
  },
  box3: {
    backgroundColor: '#e3aa1a'
  }
});

分解上面的代码,我们首先获得应用程序要消耗的可用空间的高度。 然后我们计算每个盒子的高度。 由于我们有三个方框,因此我们将其除以三。

var { height } = Dimensions.get('window');

var box_count = 3;
var box_height = height / box_count;

对于标记,盒子应包装在容器内。 通用样式在box对象中声明,并且唯一的背景颜色应用于唯一命名的对象( box1box2box3 ):


    
    
    

要使用Flexbox,必须在容器上使用flex属性。 该值是它将消耗的空间量。 如果为1 ,则意味着它将消耗所有可用空间,前提是该元素没有兄弟姐妹。 稍后,我们将看一个使用flex与同级对象的示例。

flexDirection允许您指定布局的主轴。 默认情况下,它设置为column 。 将flexDirection设置为column意味着容器的子代将垂直放置(堆叠在一起),而将其设置为row意味着将子容器水平放置(并排放置)。 要获得相等的高度,请将box的高度设置为我们先前计算的值。

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column'
  },
  box: {
    height: box_height //set this one
  },
  box1: {
    backgroundColor: '#2196F3'
  },
  box2: {
    backgroundColor: '#8BC34A'
  },
  box3: {
    backgroundColor: '#e3aa1a'
  }
});

这是一张图像,可帮助您根据指定的flexDirection可视化内容的流动方式。

React Native布局入门_第2张图片

我刚刚向您展示的方法是手动执行操作。 如果您的应用同时支持纵向和横向设备方向,则使用“ Dimensions计算元素的宽度或高度将失败。 这是因为一旦用户翻转设备,您之前计算出的宽度或高度就会错误。 React Native不会自动为您重新计算,因此该应用最终看起来很奇怪。

如果您提供正确的值,Flexbox实际上可以为您进行计算。 要在不使用Dimensions情况下实现与上述相同的布局,您要做的就是为所有框指定flex: 1而不是指定height

box: {
    flex: 1
},

现在,这是将flex与同级结合使用的示例。 现在,我们有三个具有相同flex值的兄弟姐妹。 这意味着,由于flex值相同,所以它们三个都将平均共享可用空间。 (您实际上可以使用任何flex值,只要所有子元素都具有相同的值即可。)

使用此知识,您现在可以使用页眉,内容和页脚实现布局:

//header
box1: {
    flex: 1,
    backgroundColor: '#2196F3'
},
//content
box2: {
    flex: 10,
    backgroundColor: '#8BC34A'
},
//footer
box3: {
    flex: .5,
    backgroundColor: '#e3aa1a'
}

它将是这样的:

React Native布局入门_第3张图片

请注意,这将是静态的。 因此,如果您的主要内容变得高于最大可用高度,则其余内容将被隐藏。 如果您希望内容超过该限制,则可以使用内置的ScrollView组件来自动生成垂直滚动条,就像在网页中一样。

水平堆栈布局

要实现水平堆栈布局,您要做的就是将flexDirection更改为row

container: {
    flex: 1,
    flexDirection: 'row'
  },

如果将box flex值更改回1 ,则会得到以下输出:

React Native布局入门_第4张图片

我们唯一更改的是flexDirection ,现在将其设置为row 。 由于所有框都设置为flex: 1 ,因此它们将具有相同的宽度和高度。 垂直堆栈布局中的所有想法都同样适用于这一想法。

证明内容合理

如果要控制容器中子代的分布,请使用容器上的justifyContent属性。

以下是可与此属性一起使用的五个可能的值。 在以下示例中,每个孩子的身高都降低了,以演示每个孩子的外观。 如果每个子代的flex值为1 ,您将看不到任何差异,因为它们最终将占用所有可用空间。

  • flex-start :子元素朝向起点对齐。 注意最后一个孩子下方的白色背景。 这就是您知道这是在使用flex-start原因,因为所有子项都对准起点。 到最后留下一个空白空间。
React Native布局入门_第5张图片
  • flex-end :子元素朝终点线对齐。 请注意,这次空白是在起点。
React Native布局入门_第6张图片
  • center :子元素朝中心放置。 这次,空白空间在起点和终点之间平均分配。
React Native布局入门_第7张图片
  • space-around :子元素的分布方式使得每个元素space-around均等。 这意味着外部的元素在其外侧上的空间较小,并且两个子元素之间的空间增加了一倍。
React Native布局入门_第8张图片
  • space-between :子元素的分布方式使得每个子元素之间的空间相等。
React Native布局入门_第9张图片

您可能已经注意到,每个样式属性都取决于子元素的高度或宽度。 它是依赖于宽度,如果flexDirectionrow ,并在高度如果flexDirectioncolumn

例如,如果每个子元素都使用flex来控制高度,则在垂直堆栈布局上的space-between实际上不会产生任何影响。 这是因为每个子元素之间的间隙将不再有空间要消耗。

对齐项目

乍一看, justifyContentalignItems看起来好像在做相同的事情。 它们还共享三个可能的值: flex-startflex-endcenter ,并增加了stretch值。

justifyContentalignItems之间的主要区别是分布子项的轴。 如前所述, justifyContent在分发子元素时始终使用主轴。 但是alignItems使用与主要轴相反的轴。

我们已经知道轴由已设置的flexDirection确定。 因此,如果flexDirectionrow ,则主轴从左向右流动。 这意味着横轴将从上到下流动。 另一方面,如果flexDirectioncolumn则交叉轴将从左向右流动。

下面是一些例子justifyContentalignItems实施并排的flexDirectionrow 。 第一个使用justifyContent ,第二个使用alignItems

  • flex-start :元素的位置相同,这就是为什么alignItems实现看起来完全像justifyContent
React Native布局入门_第10张图片
  • flex-end :现在我们开始看到差异。 在第一个实例中,它位于第一行行的末尾,而第二个实例似乎在最后一行的起始行。
React Native布局入门_第11张图片
  • centercenter与我们到目前为止使用的其余值具有相同的想法。 在第一种情况下,项目以x轴为中心,而在第二种情况下,项目以y轴为中心。

React Native布局入门_第12张图片

  • stretch :使用它来拉伸子元素以填充容器。 这是alignItems的默认值,因此指定此值是可选的。 您已经了解了当我们实现垂直和水平堆栈布局时这是如何工作的。

这是上面示例中使用的代码。 如果要查看它们的外观,只需使用flexDirectionjustifyContentalignItems的值即可:

import React, { Component } from 'react';
import {
  StyleSheet,
  View
} from 'react-native';

export default class AlignItems extends Component {
  render() {
    return (
      
        
            
            
            
        
        
            
            
            
        
      
    );
  }
}

const styles = StyleSheet.create({
  wrapper: {
    flex: 1
  },
  container: {
    flex: .5,
    flexDirection: 'row',
    justifyContent: 'flex-start', //replace with flex-end or center
    borderBottomWidth: 1,
    borderBottomColor: '#000'
  },
  container2: {
    flex: .5,
    flexDirection: 'row',
    alignItems: 'flex-start' //replace with flex-end or center
  },
  box: {
    width: 100,
    height: 100
  },
  box1: {
    backgroundColor: '#2196F3'
  },
  box2: {
    backgroundColor: '#8BC34A'
  },
  box3: {
    backgroundColor: '#e3aa1a'
  }
});

如果要指定容器中各个元素的对齐方式,则可以使用alignSelf属性。 align-items所有可能值也适用于此属性。 因此,例如,您可以将单个元素对齐到其容器的右侧,而将其余所有元素都对齐到左侧。

网格布局

React Native并没有真正提供网格布局系统,但是Flexbox足够灵活以创建一个网格布局系统。 通过使用到目前为止所学的知识,我们可以使用Flexbox重新创建Grid布局。 这是一个例子:

React Native布局入门_第13张图片

这是创建布局的代码:

import React, { Component } from 'react';
import {
  StyleSheet,
  View
} from 'react-native';

export default class GridLayout extends Component {
  render() {
    return (
      
          
            
            
            
          
          
          
            
            
            
          

          
            
            
            
          

          
            
            
            
          

          
            
            
          

          
            
          
      
    );
  }
}


const styles = StyleSheet.create({
  row: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 10
  },
  box: {
    flex: 1,
    height: 100,
    backgroundColor: '#333',
  },
  box2: {
    backgroundColor: 'green'
  },
  box3: {
    backgroundColor: 'orange'
  },
  two: {
    flex: 2
  }
});

从上面的代码中,您可以看到我们正在模仿它们在CSS网格框架中通常执行的操作。 每行都包装在单独的视图中,并且网格项位于其中。 默认的flex1应用于每个项目,因此它们将平均共享每一行上的可用空间。 但是对于需要占用较大空间的项目,将应用较高的flex值。 这将自动调整其他项目的宽度,以便容纳所有项目。

如果要在行中的每个项目之间添加空格,则可以为每个项目添加填充,然后在每个项目内部创建一个框。

结果为以下输出:

React Native布局入门_第14张图片

绝对布局

React Native仅支持absoluterelative定位。 但是,这不应该限制您,因为您始终可以将它们与Flexbox结合使用,以将不同的元素放置在所需的任何位置。

让我们看看如何完成以下任务:



React Native布局入门_第15张图片

如果我们对浏览器中可用的定位值具有完整的命令,则可以轻松实现此目的。 但是由于我们在React Native中,所以我们需要首先考虑Flexbox的方式,然后再对小盒子使用CSS定位。

使用Flexbox,可以通过两种方式实现。 您可以将rowcolumn用于主容器的flexDirection 。 如何安排不同元素取决于您选择哪种方法。 在这里,我们将对flexDirection使用row ,以便将屏幕分为三列。 第一列将包含橙色框,第二列将包含黑色,灰色和绿色框,第三列将包含蓝色和紫色小框。

import React, { Component } from 'react';
import {
  StyleSheet,
  View
} from 'react-native';

export default class Positioning extends Component {
  render() {
      return (
      

        
          
          
        
          
        
          
            
                  
          
          
            
          
        
  
        
          
            
          
          
        
        
      
  	);
  }
}

如果您已经知道每个元素的布局方式,那么只需应用到目前为止所学的知识即可。 毕竟,我们实际上不需要在大盒子上应用CSS定位,只需要在小盒子上应用CSS定位。

第一列只有橙色框,因此在其容器中应用justifyContent: 'center'应该可以解决问题。 如果您已经忘记了, flexDirection默认为column 。 这意味着,如果将justifyContent设置为center ,则子代将在Y轴的中心对齐。

第二列与第一列基本具有相同的想法,只是这次我们不想将所有框对齐到中心。 我们想要的是它们彼此之间具有相等的空间,并实现justifyContent: 'space-between'可以完成这项工作。 但是同时,我们还希望将所有子项都放在X轴上alignItems: 'center'因此我们使用alignItems: 'center'

这里唯一棘手的部分是,您不应将任何width属性应用于灰色框,因为我们希望它一直伸展以消耗其父级的整个宽度。 由于我们没有应用任何width ,因此我们应该将alignSelf: 'stretch'应用于灰色框,以便它将占用其父级的全部宽度。

接下来,要使红色小框的位置稍微偏离其相对位置,我们使用position: relative ,然后应用topleft值,因为其相对位置在其父级的左上角附近。

至于小橙色框,我们使用position: 'absolute'因为我们需要将其对准其父级的右上角。 之所以可行,是因为React Native中绝对定位的元素已绑定到其父元素。

第三列基本上采用了相同的想法,因此我不再赘述。

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row'
  },
  left: {
    flex: 1,
    justifyContent: 'center'
  },
  middle: {
    flex: 5,
    justifyContent: 'space-between',
    alignItems: 'center'
  },
  right: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'flex-end'
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: '#333'
  },
  big_green_box: {
    backgroundColor: 'green'
  },
  big_orange_box: {
    backgroundColor: 'orange'
  },
  big_lightblue_box: {
    backgroundColor: '#03A9F4'
  },
  big_gray_box: {
    height: 100,
    alignSelf: 'stretch',
    backgroundColor: '#ccc'
  },  
  inner_box: {
    width: 20,
    height: 20,
  },
  red_box: {
    position: 'relative',
    backgroundColor: 'red',
    top: 10,
    left: 10
  },
  orange_box: {
    position: 'absolute',
    backgroundColor: 'orange',
    top: 10,
    right: 10
  },
  purple_box: {
    position: 'absolute',
    backgroundColor: 'purple',
    bottom: 10,
    right: 10
  },
  black_box: {
    position: 'relative',
    backgroundColor: 'black'
  }
});

接下来,让我们尝试实现固定的页眉和页脚布局。 这通常在具有标签导航的应用中找到; 选项卡固定在屏幕底部,而主要内容可以滚动。

为此,我们需要使用ScrollView组件,以便如果主要内容超出了容器的高度,React Native将自动生成一个垂直滚动条。 这使我们可以在主要内容容器中添加marginTopmarginBottom ,以便固定的页眉和页脚不会阻碍主要内容。 另外,请注意,页眉和页脚的left值和right值都设置为0这样它们将占用整个设备的宽度。

import React, { Component } from 'react';
import {
  StyleSheet,
  View,
  ScrollView
} from 'react-native';

export default class FixedHeaderFooter extends Component {
  render() {
      return (
      
        
        
          
            
            
            
            
            
            
            
          
        
        
      
  	);
  }
}


const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'center'
  },
  header: {
    height: 40,
    position: 'absolute',
    left: 0,
    right: 0,
    top: 0,
    backgroundColor: '#03A9F4',
    zIndex: 10
  },
  content: {
    alignItems: 'center',
    marginTop: 50,
    marginBottom: 40
  },
  footer: {
    height: 40,
    position: 'absolute',
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: '#8BC34A'
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: '#333',
    marginBottom: 10
  }
});

外观如下:

React Native布局入门_第16张图片

第三方图书馆

React Native背后有一个庞大的社区,因此,毫无疑问已经创建了一些库来简化布局的实现。 在本节中,我将向您介绍一个名为React Native Easy Grid的库。 您可以使用它来描述如何通过使用GridRowCol组件来布局应用程序。

您可以使用以下命令进行安装:

npm install react-native-easy-grid --save

导入库并提取文件中的不同组件。

import React, { Component } from 'react';
import {
  StyleSheet,
  View
} from 'react-native';

import { Col, Row, Grid } from "react-native-easy-grid";

Grid组件用于包装所有内容。 Col用于创建列, Row用于创建行。 您可以为RowCol都指定一个size属性,尽管我们仅在下面的Row中使用了它。 如果未指定大小,它将在Col实例之间平均分配可用空间。

在这种情况下,只有两个,因此整个屏幕分为两列。 然后,第一列分为两行。 在这里,我们指定了一个size ,但是如果您只需要相同大小的行,则可以实际跳过它,如下所示。

export default class FlexboxGridLibrary extends Component {
  
  render() {
    return (
        
            
                
                
            
            
        
    );
  }
  
}

完成后,您所要做的就是为行和列添加样式:

const styles = StyleSheet.create({
  orange_box: {
    backgroundColor: 'orange'
  },
  green_box: {
    backgroundColor: 'green'
  },
  gray_box: {
    backgroundColor: 'gray'
  }
});

您已经注意到,React Native Easy Grid具有非常直观的API。

结论

在本教程中,您学习了如何布局React Native应用程序。 具体来说,您学习了如何使用React Native的Flexbox定位事物。 您还学习了如何使用React Native Easy Grid,这使Flexbox的实现更加容易。

在即将发布的教程中,我们将通过重新创建应用程序中常见的UI元素将您学到的所有知识付诸实践,例如日历,列表和标签导航。

翻译自: https://code.tutsplus.com/tutorials/get-started-with-layouts-in-react-native--cms-27418

你可能感兴趣的:(python,java,css,html,vue,ViewUI)