翻译 | 《JavaScript Everywhere》第22章 挪动应用程序shell
写在最后面
大家好呀,我是毛小悠,是一位前端开发工程师。正在翻译一本英文技术书籍。
为了进步大家的浏览体验,对语句的构造和内容略有调整。如果发现本文中有存在瑕疵的中央,或者你有任何意见或者倡议,能够在评论区留言,或者加我的微信:code_maomao,欢送互相沟通交流学习。
(゚∀゚)..:*☆哎哟不错哦
第22章 挪动应用程序shell
我妻子是一位摄影师,这意味着她的大部分生存都是基于在矩形框中构图。在摄影中,有很多变量-物体,光线,角度,然而图像的比例保持一致。在这种限度下,不堪设想的事件产生了,塑造了咱们对待和记住四周世界的形式。挪动利用程序开发提供了相似的机会。在玲珑的矩形屏幕的束缚下,咱们能够构建具备沉迷式用户体验的功能强大的应用程序。
在本章中,咱们将开始为应用程序构建shell
。为此,咱们首先将认真钻研React Native
组件的一些要害构建块。而后,咱们将通过React Native
的内置款式反对以及咱们抉择的CSS-in-JS
库款式组件,钻研如何将款式利用于咱们的应用程序。在介绍了如何利用款式之后,咱们将看看如何将路由集成到咱们的应用程序中。最初,咱们将摸索如何应用图标轻松加强咱们的利用程序界面。
React Native构建块
让咱们先来看一下React Native
应用程序的根本构建块。你可能曾经猜到React Native
应用程序蕴含用JSX
编写的React
组件。然而,如果没有HTML
页面的DOM
(文档对象模块),这些组件到底有什么用?咱们可用于从src/Main.js
的“ Hello World
”组件开始。当初,我曾经删除了款式:
import React from 'react';import { Text, View } from 'react-native';const Main = () => {return (<View><Text>Hello world!</Text></View>);};export default Main;
在此标记中,有两个驰名的JSX
标签 :
和 .
。如果你有网页开发教训,就晓得标签与标签的用处大致相同。它是咱们应用程序内容的容器。靠它们本人并不能做很多事,然而它们蕴含了咱们应用程序的所有内容,能够互相嵌套,并能够利用款式。咱们的每个组件都将蕴含在中。
在React Native
中,你能够在Web
任何中央应用标签。毫无疑问,该标签用于蕴含咱们利用中的任何文本。
然而,与网页不同,该标签用于所有文本。咱们还能够通过应用JSX
元素来增加图片到咱们的利用中。
让咱们更新咱们的 src/Main.js
文件以蕴含图像。要做到这一点,咱们从React Native导入了Image
组件并应用一个有src属性的标记(见图22-1
):
import React from 'react';import { Text, View, Image } from 'react-native';const Main = () => {return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Hello world!</Text><Image source={require('../assets/images/hello-world.jpg')} /></View>);};export default Main;
后面的代码在视图中渲染了一些文本和图像。你可能会留神到,咱们的标记和JSX
标记是传递的属性,这些属性使咱们可能管制特定的行为(在这种状况下,是视图的款式和图像的起源)。
将属性传递给元素能够使咱们扩大元素的各种附加性能。React Native
的API
文档对每个元素可用的属性进行了分类。
图22-1
。应用<Image
>标签,咱们能够将图像增加到咱们的应用程序中(Windell Oskay
摄)
咱们的应用程序并没有做很多事件,然而在下一节中,咱们将探讨如何应用React Native
的内置款式反对和款式化组件来改善外观。
款式和款式组件
作为应用程序开发人员和设计师,咱们心愿可能对应用程序进行款式设置,能够具备良好的外观、感觉和用户体验。有许多UI
组件库,例如NativeBase
或React Native Elements
,通常提供了许多预约义且可自定义的组件。
这些都是值得一看的,但出于咱们的目标,让咱们摸索如何组合本人应用程序的款式和布局。
正如咱们曾经看到的,React Native
提供了一个style
属性,该属性容许咱们将自定义款式利用于应用程序中的任何JSX
元素。款式名称和值与CSS
的款式名称和值匹配,除了名称应用camelCase
编写外,例如lineHeight
和backgroundColor
。让咱们更新/src/Main.js
文件,使其蕴含元素的某些款式(参见图22-2
):
const Main = () => {return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text style={{ color: '#0077cc', fontSize: 48, fontWeight: 'bold' }}>Hello world!</Text><Image source={require('../assets/images/hello-world.jpg')} /></View>);};
图22-2
应用款式咱们能够调整<Text
>元素的外观
你可能会认为,在元素级别利用款式会很快变得难以保护。咱们能够应用React Native
的StyleSheet
库来帮忙组织和重用咱们的款式。
首先,咱们须要将StyleSheet
增加到导入列表中(图22-3
):
import { Text, View, Image, StyleSheet } from 'react-native';
当初咱们能够形象出款式:
const Main = () => {return (<View style={styles.container}><Text style={styles.h1}>Hello world!</Text><Text style={styles.paragraph}>This is my app</Text><Image source={require('../assets/images/hello-world.jpg')} /></View>);};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center'},h1: {fontSize: 48,fontWeight: 'bold'},paragraph: {marginTop: 24,marginBottom: 24,fontSize: 18}});
弹性盒Flexbox
React Native
应用CSS flexbox
算法定义布局款式。咱们不会深刻介绍flexbox
,然而React Native
提供的文档分明地阐明了flexbox
及其如何在屏幕上排列元素的案例。
[外链图片转存失败,源站可能有防盗链机制,倡议将图片保留下来间接上传(img-z9Ipy9fi-1606433567748)(http://vipkshttp0.wiz.cn/ks/s...]
图22-3
通过应用样式表,咱们能够缩放应用程序的款式
款式化的组件
只管React Native
的内置款式属性和StyleSheets
能够提供咱们开箱即用的所有性能,但它们远不是咱们设计应用程序款式的惟一抉择。
咱们还能够利用风行的Web CSS-in-JS
解决方案,例如Styled Components
和Emotion
。我认为这些提供了更简洁的语法,与CSS
更加严密地联合在一起,并限度了Web
和挪动利用程序代码库之间所需的转换的代码量。应用这些启用了Web CSS-in-JS
库也为跨平台共享款式或组件发明了机会。为了实现咱们的目标,让咱们看一下如何使上一个示例适应应用Styled Components
库。首先,在src/Main.js
中,咱们将导入库的本机版本:
import styled from 'styled-components/native'
从这里咱们能够将款式迁徙到款式化组件语法。如果曾经依照了第13
章的阐明进行操作,则此语法应该十分相熟。咱们的src/Main.js
文件的最终代码变为:
import React from 'react';import { Text, View, Image } from 'react-native';import styled from 'styled-components/native';const StyledView = styled.View`flex: 1;justify-content: center;`;const H1 = styled.Text`font-size: 48px;font-weight: bold;`;const P = styled.Text`margin: 24px 0;font-size: 18px;`;const Main = () => {return (<StyledView><H1>Hello world!</H1><P>This is my app.</P><Image source={require('../assets/images/hello-world.jpg')} /></StyledView>);};export default Main;
款式化的组件大写
在款式化组件库中,元素名称必须始终大写。这样,咱们当初能够将自定义款式利用于咱们的应用程序,并能够抉择应用React Native
的内置款式零碎或款式化组件库。
路由
在网页上,咱们能够应用HTML
锚链接将一个HTML
文档链接到任何其余文档,包含咱们本人网站上的文档。对于JavaScript
驱动的应用程序,咱们应用路由将JavaScript
渲染的模板链接在一起。那么挪动应用程序呢?对于这些,咱们将在屏幕之间路由用户。在本节中,咱们将探讨两种常见的路由类型:基于选项卡的导航和堆栈导航。
应用React
导航的选项卡式路由
为了执行路由,咱们将利用React Navigation
库,这是React Native
和Expo
团队举荐的路由解决方案。最重要的是,它使实现带有平台特定的外观通用路由模式变得非常简单。
首先,让咱们首先在src
目录中创立一个名为screens
的新目录。在screens
目录中,让咱们创立三个新文件,每个文件蕴含一个十分根本的React
组件。
在src/screens/favorites.js
中增加以下内容:
import React from 'react';import { Text, View } from 'react-native';const Favorites = () => {return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Favorites</Text></View>);};export default Favorites;
在src/screens/feed.js
中增加它:
import React from 'react';import { Text, View } from 'react-native';const Feed = () => {return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Feed</Text></View>);};export default Feed;
最初,将其增加到src/screens/mynotes.js
中:
import React from 'react';import { Text, View } from 'react-native';const MyNotes = () => {return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>My Notes</Text></View>);};export default MyNotes;
而后,咱们能够在src/screens/index.js
中创立一个新文件,用作咱们应用程序路由的根目录。咱们将从导入初始的react
和react-navigation
依赖关系开始:
import React from 'react';import { createAppContainer } from 'react-navigation';import { createBottomTabNavigator } from 'react-navigation-tabs';// import screen componentsimport Feed from './feed';import Favorites from './favorites';import MyNotes from './mynotes';
导入这些依赖项后,咱们能够应用React Navigation
的createBottomTabNavigator
,在这三个屏幕之间创立一个标签导航器,定义应在咱们的导航中显示哪些React
组件屏幕:
const TabNavigator = createBottomTabNavigator({FeedScreen: {screen: Feed,navigationOptions: {tabBarLabel: 'Feed',}},MyNoteScreen: {screen: MyNotes,navigationOptions: {tabBarLabel: 'My Notes',}},FavoriteScreen: {screen: Favorites,navigationOptions: {tabBarLabel: 'Favorites',}}});// create the app containerexport default createAppContainer(TabNavigator);
最初,让咱们更新src/Main.js
文件,除了导入路由器之外什么也不做。当初应简化为以下内容:
import React from 'react';import Screens from './screens';const Main = () => {return <Screens />;};export default Main;
通过在终端中输出npm start
命令,确保你的应用程序正在运行。当初,你应该在屏幕底部看到选项卡导航,在其中点击选项卡会将你转到适当的屏幕(图22-4
)。
图22-4
当初咱们能够应用选项卡式导航在屏幕之间导航
堆栈导航
第二种路由抉择类型是堆栈导航,其中概念上将屏幕“重叠”在一起,从而使用户能够更深刻地浏览堆栈。思考一个新闻应用程序,用户在其中查看文章的摘要。用户能够点击新闻文章题目,并在堆栈中更深刻地浏览到文章内容。
而后,他们能够单击“后退”按钮,导航回文章提要,或者导航到另一个文章题目,从而更深刻地浏览堆栈。
在咱们的应用程序中,咱们心愿用户可能从笔记的摘要切换到笔记本身并返回。
让咱们看看如何为每个屏幕实现堆栈导航。首先,让咱们创立一个新的NoteScreen
组件,它将蕴含堆栈中的第二个屏幕。应用起码的React Native
组件在src/screens/note.js
上创立一个新文件:
import React from 'react';import { Text, View } from 'react-native';const NoteScreen = () => {return (<View style={{ padding: 10 }}><Text>This is a note!</Text></View>);};export default NoteScreen;
接下来,咱们将对路由器进行更改,启用NoteScreen
组件的重叠导航。为此,咱们将从react-navigation-stack
以及新的note.js
组件导入createStackNavigator
。在src/screens/index.js
中,将导入内容更新如下:
import React from 'react';import { Text, View, ScrollView, Button } from 'react-native';import { createAppContainer } from 'react-navigation';import { createBottomTabNavigator } from 'react-navigation-tabs';// add import for createStackNavigatorimport { createStackNavigator } from 'react-navigation-stack';// import screen components, including note.jsimport Feed from './feed';import Favorites from './favorites';import MyNotes from './mynotes';import NoteScreen from './note';
通过导入咱们的库和文件,咱们能够实现堆栈导航性能。在咱们的路由器文件中,咱们必须通知React Navigation
哪些屏幕是“可重叠的”。对于咱们每个选项卡式路由,咱们心愿用户可能导航到“笔记”屏幕。持续并按如下所示定义这些堆栈:
const FeedStack = createStackNavigator({Feed: Feed,Note: NoteScreen});const MyStack = createStackNavigator({MyNotes: MyNotes,Note: NoteScreen});const FavStack = createStackNavigator({Favorites: Favorites,Note: NoteScreen});
当初,咱们能够更新TabNavigator
来援用堆栈,而不是单个屏幕。为此,请更新每个TabNavigator
对象中的screen
属性:
const TabNavigator = createBottomTabNavigator({FeedScreen: {screen: FeedStack,navigationOptions: {tabBarLabel: 'Feed'}},MyNoteScreen: {screen: MyStack,navigationOptions: {tabBarLabel: 'My Notes'}},FavoriteScreen: {screen: FavStack,navigationOptions: {tabBarLabel: 'Favorites'}}});
总之,咱们的src/screens/index.js
文件应如下所示:
import React from 'react';import { Text, View, ScrollView, Button } from 'react-native';import { createAppContainer } from 'react-navigation';import { createBottomTabNavigator } from 'react-navigation-tabs';import { createStackNavigator } from 'react-navigation-stack';// import screen componentsimport Feed from './feed';import Favorites from './favorites';import MyNotes from './mynotes';import NoteScreen from './note';// navigation stackconst FeedStack = createStackNavigator({Feed: Feed,Note: NoteScreen});const MyStack = createStackNavigator({MyNotes: MyNotes,Note: NoteScreen});const FavStack = createStackNavigator({Favorites: Favorites,Note: NoteScreen});// navigation tabsconst TabNavigator = createBottomTabNavigator({FeedScreen: {screen: FeedStack,navigationOptions: {tabBarLabel: 'Feed'}},MyNoteScreen: {screen: MyStack,navigationOptions: {tabBarLabel: 'My Notes'}},FavoriteScreen: {screen: FavStack,navigationOptions: {tabBarLabel: 'Favorites'}}});// create the app containerexport default createAppContainer(TabNavigator);
如果咱们在模拟器或设施上的Expo
应用程序中关上应用程序,则不会发现显著区别。这是因为咱们尚未向重叠导航增加链接。让咱们更新src/screens/feed.js
组件以包含一个重叠的导航链接。
为此,首先包含React Native
的Button
依赖项:
import { Text, View, Button } from 'react-native';
当初,咱们能够包含一个按钮,在按下该按钮时,将导航到note.js
组件的内容。咱们将传递组件props
,其中将蕴含导航信息,并增加一个蕴含题目和onPress
道具的:
const Feed = props => {return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Note Feed</Text><Button title="Keep reading" onPress={() => props.navigation.navigate('Note')}/></View>);};
这样,咱们应该可能在屏幕之间进行导航。单击“Feed”屏幕中的按钮以导航至“Node”屏幕,而后单击箭头以返回(图22-5
)。
图22-5
单击按钮链接将导航到新屏幕,而单击箭头将使用户返回上一屏幕
增加屏幕题目
增加堆栈导航器会主动在咱们的应用程序顶部增加标题栏。咱们能够设置款式,甚至删除该顶部栏。当初,让咱们在堆栈顶部的每个屏幕上增加一个题目。为此,咱们将在组件自身之外设置组件NavigationOptions
。在src/screens/feed.js
中:
import React from 'react';import { Text, View, Button } from 'react-native';const Feed = props => {// component code};Feed.navigationOptions = {title: 'Feed'};export default Feed;
咱们能够对其余屏幕组件反复此过程。
在src/screens/favorites.js
中:
Favorites.navigationOptions = {title: 'Favorites'};
在src/screens/mynotes.js
中:
MyNotes.navigationOptions = {title: 'My Notes'};
当初,咱们每个屏幕的顶部导航栏都将蕴含一个题目(图22-6
)。
图22-6
在navigationOptions
中设置题目会将其增加到顶部导航栏
Icons
目前,咱们的导航性能已实现,但短少可视化组件以使用户应用更敌对。值得庆幸的是,Expo
使在咱们的应用程序中蕴含图标变得异样容易。咱们能够搜寻Expo
提供的所有图标expo.github.io/vector-icons
。包含许多图标集,例如Ant Design
,Ionicons
,Font Awesome
,Entypo
,Foundation
,Material
图标和Material Community
图标。这为咱们提供了开箱即用的多种抉择。
让咱们在选项卡式导航中增加一些图标。首先,咱们必须导入咱们要应用的图标集。在咱们的案例中,咱们将通过在src/screens/index.js
中增加以下内容来应用Material Community
图标:
import { MaterialCommunityIcons } from '@expo/vector-icons';
当初,咱们想在组件中应用图标的任何中央,都能够将其蕴含在JSX
中,包含设置属性,例如大小和色彩:
<MaterialCommunityIcons name="star" size={24} color={'blue'} />
咱们将图标增加到标签导航中。React Navigation
蕴含一个名为tabBarIcon
的属性,该属性容许咱们设置图标。咱们能够将此作为函数传递,使咱们可能设置tintColor
,以便流动选项卡图标的色彩与非流动图标的色彩不同:
const TabNavigator = createBottomTabNavigator({FeedScreen: {screen: FeedStack,navigationOptions: {tabBarLabel: 'Feed',tabBarIcon: ({ tintColor }) => (<MaterialCommunityIcons name="home" size={24} color={tintColor} />)}},MyNoteScreen: {screen: MyStack,navigationOptions: {tabBarLabel: 'My Notes',tabBarIcon: ({ tintColor }) => (<MaterialCommunityIcons name="notebook" size={24} color={tintColor} />)}},FavoriteScreen: {screen: FavStack,navigationOptions: {tabBarLabel: 'Favorites',tabBarIcon: ({ tintColor }) => (<MaterialCommunityIcons name="star" size={24} color={tintColor} />)}}});
这样,咱们的选项卡式导航将显示图标(图22-7
)。
图22-7
咱们应用程序的导航当初包含图标
论断
在本章中,咱们介绍了如何构建React Native
应用程序的根本组件。当初,你能够创立组件,向其中增加款式并在它们之间导航。心愿通过此根本设置,你能够看到React Native
的惊人后劲。借助起码的新技术,你曾经能够打造令人印象粗浅且业余的挪动应用程序的终点。在下一章中,咱们将应用GraphQL
在应用程序中蕴含来自API
的数据。
如果有了解不到位的中央,欢送大家纠错。如果感觉还能够,麻烦您点赞珍藏或者分享一下,心愿能够帮到更多人。