在本系列中,您将学习如何使用React Native创建移动应用程序中常用的页面布局。 您正在创建的布局将无法使用-相反,本系列的主要重点是让您动手以布局React Native应用程序中的内容。
为了跟随本系列的进行,在您阅读本教程中的分步说明之前,我建议您先尝试自己重新创建每个屏幕。 仅仅阅读本教程,您将不会真正从中受益! 首先尝试,然后再在此处查找答案。 如果成功使它看起来像原始屏幕,则将您的实现与我的实现进行比较。 然后自己决定哪个更好!
在本系列的第三篇文章中,您将创建以下照片库页面:
画廊通常用于显示相关内容的集合,从而仅显示必要的信息。 大多数情况下,其中包括照片,标题和其他相关信息。
以下是在野外使用的这种类型的布局的几个示例:
项目设置
当然,第一步是建立一个新的React Native项目:
react-native init react-native-common-screens
设置项目后,打开index.android.js
文件,并将默认代码替换为以下代码:
import React, { Component } from 'react';
import {
AppRegistry
} from 'react-native';
import Gallery from './src/pages/Gallery';
export default class ReactNativeCommonScreens extends Component {
render() {
return (
<Gallery />
);
}
}
AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);
创建一个src/pages
文件夹,并在其中创建一个Gallery.js
文件。
您还需要react-native-vector-icons
包。 专门用于页脚中的图标。
npm install --save react-native-vector-icons
打开android/app/build.gradle
文件并添加对该包的引用:
dependencies {
//rest of the dependencies are here at the top
compile project(':react-native-vector-icons') //add this
}
通过在底部添加以下内容,对android/settings.gradle
文件执行相同的操作:
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
打开android/app/src/main/java/com/react-native-common-screens/MainApplication.java
并导入软件包:
import java.util.Arrays;
import java.util.List;
import com.oblador.vectoricons.VectorIconsPackage; //add this
最后,初始化程序包:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new VectorIconsPackage() //add this
);
}
创建图库页面
好的,既然您已尝试自己编写布局代码(不作弊,对吗?),我将向您展示如何构建实现。
与前两页不同,图库页面需要一些图像作为其主要内容。 您可以转到Google搜索图像或从GitHub存储库下载图像。 我使用的所有图像均被各自所有者标记为可重复使用,因此您可以根据需要自由使用它们。 获得图像后,将其保存在src/images
目录中。 由于图像的布局方式,所有图像均应具有相等的尺寸。
首先创建文件( src/pages/Gallery.js
),然后添加样板代码:
import React, { Component } from 'react';
import {
StyleSheet,
View,
ScrollView,
Image,
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import Button from '../components/Button';
export default class Gallery extends Component {
...
}
该页面需要一个constructor()
函数,您可以在其中定义要使用的图像的路径。 在React Native中,您引用工作目录中的图像的方式是像对JavaScript模块一样要求它们。 还需要注意的是,您不能动态生成图像路径,因此必须手动提供实际路径。
constructor(props) {
super(props);
this.state = {
photos: [
{
label: 'beach',
src: require('../images/beach.jpg')
},
{
label: 'bridge',
src: require('../images/bridge.jpg')
},
{
label: 'fields',
src: require('../images/fields.jpg')
},
{
label: 'mountains',
src: require('../images/mountains.jpg')
},
{
label: 'sunflower',
src: require('../images/sunflower.jpg')
},
{
label: 'sunset',
src: require('../images/sunset.jpg')
},
{
label: 'lake',
src: require('../images/lake.jpg')
},
{
label: 'nature',
src: require('../images/nature.jpg')
},
{
label: 'pink',
src: require('../images/pink.jpg')
},
{
label: 'rails',
src: require('../images/rails.jpg')
},
]
};
}
您实际上不需要在状态中定义这些值,因为值不会更改。 您实际上可以在一个单独的文件中定义它们,将其导入,将其分配给一个变量,然后直接使用它。 但是为了简单起见,我决定将所有内容都置于状态中。
在render()
方法内部,您将打破将所有内容包装在ScrollView
组件内的趋势,因为屏幕最下部的tab组件应具有固定的位置。 这意味着,即使照片超出了可用高度,标签也应保持在原处。 为此,请使用View
组件包装所有内容,并将照片集仅包装在ScrollView
。 这使您可以将滚动条仅应用于照片集的容器:
render() {
return (
<View style={styles.container}>
<ScrollView style={styles.gallery}>
{ this.renderGallery() }
</ScrollView>
<View style={styles.tabs}>
</View>
);
}
现在您可能会开始在这里看到一个模式。 每次需要在render()
函数中使用JavaScript代码时,都应创建一个单独的函数来保存该代码,而不是将其直接放在render()
函数中。 这样可以使其保持苗条和清洁。
现在让我们继续进行样式设计。 尽管这次没有使用ScrollView
来包装所有内容,但是需要注意的是,您仍然必须向主容器提供flex: 1
,以便占用整个可用空间。
container: {
flex: 1,
flexDirection: 'column'
},
gallery: {
flexDirection: 'column'
},
tabs: {
flexDirection: 'row',
backgroundColor: '#333',
padding: 20
},
tab: {
flex: 1
},
icon: {
textAlign: 'center'
},
该renderGallery()
函数是非常相似的renderWeeks()
函数,我们在前面的教程,这是我们用来渲染日历页中使用。 如果您想重新了解其工作原理,请继续阅读日历页面上的上一教程 。 您需要知道的是resizeMode
已应用于Image
。 在这种情况下,将其设置为cover
,这将使图像占据其容器的整个可用空间,同时仍保持其纵横比。 如果原始图像较小,则对于具有较大屏幕的设备,图像会被稍微炸掉。
renderGallery() {
var count = 0;
var previous_item = '';
var pairs = this.getPairsArray(this.state.photos);
return pairs.map((item, index) => {
return (
<View style={styles.item} key={index}>
<Image
resizeMode={Image.resizeMode.cover}
style={styles.photo}
source={item[0].src} />
<Image
resizeMode={Image.resizeMode.cover}
style={styles.photo}
source={item[1].src} />
</View>
);
});
}
这是getPairsArray()
函数:
getPairsArray(photos) {
var pairs_r = [];
var pairs = [];
var count = 0;
photos.forEach((item) => {
count += 1;
pairs.push(item);
if(count == 2){
pairs_r.push(pairs)
count = 0;
pairs = [];
}
});
return pairs_r;
}
最后,这是每行( item
)和照片( photo
)的样式。 注意在实际照片上使用flex: 1
。 这样做是因为Image
组件本身是其自己的容器。 您希望容器本身占据每一行可用空间的一半,这就是为什么应该分配flex
属性的原因。 如果不这样做,则只会消耗照片所需的尺寸,而您先前添加的resizeMode
甚至不会起作用。
item: {
flex: 1,
flexDirection: 'row',
},
photo: {
flex: 1
}
结论
而已! 在本教程中,您学习了如何实现图库页面的布局。 我们专注于在布置React Native应用程序时如何处理图像。 通常,您必须结合使用flex
和resizeMode
才能使图像按照您希望的方式流动。 我的解决方案与您的解决方案相比如何? 在下面的讨论论坛中让我们知道。
翻译自: https://code.tutsplus.com/tutorials/common-react-native-app-layouts-gallery-page--cms-27642