翻译 |《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 components
import 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 container
export 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 createStackNavigator
import {createStackNavigator} from 'react-navigation-stack';
// import screen components, including note.js
import 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 components
import Feed from './feed';
import Favorites from './favorites';
import MyNotes from './mynotes';
import NoteScreen from './note';
// navigation stack
const FeedStack = createStackNavigator({
Feed: Feed,
Note: NoteScreen
});
const MyStack = createStackNavigator({
MyNotes: MyNotes,
Note: NoteScreen
});
const FavStack = createStackNavigator({
Favorites: Favorites,
Note: NoteScreen
});
// navigation tabs
const TabNavigator = createBottomTabNavigator({
FeedScreen: {
screen: FeedStack,
navigationOptions: {tabBarLabel: 'Feed'}
},
MyNoteScreen: {
screen: MyStack,
navigationOptions: {tabBarLabel: 'My Notes'}
},
FavoriteScreen: {
screen: FavStack,
navigationOptions: {tabBarLabel: 'Favorites'}
}
});
// create the app container
export 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
的数据。
如果有了解不到位的中央,欢送大家纠错。如果感觉还能够,麻烦您点赞珍藏或者分享一下,心愿能够帮到更多人。