目录
- ios环境搭建采坑
- android环境搭建采坑
- react-native基础组件的使用
- antd-mobile-rn组件库的集成
- react-native使用字体图标库
- react-native如何做启动屏和欢迎页
- react-naviation@5.x 导航组件的使用
前言
环境搭建以及基础组件的使用后,下一步为了能组织成规模的app,导航navigation是必然的,就像前端工程离不开路由router一样。根据资料的学习,了解到react-native有过很多版本的navigation组件,其中包括如下:
- NavigationIOS:只针对iOS平台开发,它是基于 UINavigationController 封装的,所以看起来很像
- Navigator : 使⽤JS来实现,将逐步被替代,⽬前仍然可⽤
- NavigationExperimental: 最早的导航组件,⽬前已经完全弃⽤
- react-navigation : 目前最流行的导航组件,兼容ios和安卓,也是本篇文章重点介绍的组件
react-navigation的安装
在你的 React Native 项⽬中安装 react-navigation 这个包
# yarn 安装
yarn add @react-navigation/native
# npm 安装
npm install @react-navigation/native -S
然后,安装 react-naviation的相关依赖
# 使用yarn 安装
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
# 使用npm 安装
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view -S
从React Native 0.60及更高版本开始,链接是自动的。 因此,您无需运行react-native链接。
# iOS操作
cd ios
pod install
要完成react-native-gesture-handler的安装,请在条目文件(例如index.js或App.js)的顶部(确保它位于顶部,并且没有其他内容)之前添加以下内容:
import 'react-native-gesture-handler';
例如:
import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
export default function App() {
return (
<NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
);
}
导航器介绍
导航器也可以看成是⼀个普通的React组件,你可以通过导航器来定义你的APP中的导航结构。导航器 还可以渲染通⽤元素,例如可以配置的标题栏和选项卡栏。 在react-navigation中有以下类型的导航器:
- stacktackNavigator:类似普通的Navigator,导航上⽅导航栏
- createBottomTabNavigator:底部tab导航
- createMaterialTopTabNavigator:屏幕顶部的Material设计主题标签栏
- createDrawerNavigator:抽屉效果,侧边滑出
- createSwitchNavigator:SwitchNavigator的⽤途是⼀次只显示⼀个⻚⾯,常⽤于welcome⻚⾯或者登陆⻚⾯,这种⻚⾯没有回退操作。
你可以通过以上⼏种导航器来创建你的APP,可以是其中⼀个也可以多个组合,这个可以根据具体的应 ⽤场景并结合每⼀个导航器的特性进⾏选择。
NavigationContainer --各种Navigator的容器
这是一个用来装载各个Navigator的容器,整个工程有且只有一个。 如下:
<NavigationContainer onStateChange={()=>this.stateChange()}>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} options={{ title: '首页' }} />
<Stack.Screen name="My" component={My} options={{
title:"我的"
}}/>
</Stack.Navigator>
</NavigationContainer>
这个组件的常用的props有
- theme 设置的主题
- onStateChange 导航发生变化时的事件监听
- onReady 导航组件准备好时的事件监听
stacktackNavigator 用的最多的导航
stacktackNavigator是最普通也是使用最为广泛的导航,提供APP屏幕之间切换的能⼒,它是以栈的形式还管理屏幕之间的切换,新切换到的屏幕会放在栈的顶部。
stacktackNavigator 被配置为具有熟悉的iOS和Android外观 & 感觉:新屏幕从iOS右侧滑⼊,从Android底部淡⼊。 在iOS上,stack navigator 也可以配置为屏幕从底部滑⼊的模式样式。
安装stackNavigator
使用npm或者yarn都可以轻松安装
npm install @react-navigation/stack
创建stackNavigator
创建stackNavigation很简单,调用@react-navigation/stack中的createStackNavigator方法创建一个Stack组件,并且需要NavigationContainer组件进行包裹才可以使用。如下: 其中Home和My是不同的页面组件。构建的方式和react-router很类似。
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import Home from './pages/home/';
import My from "./pages/my"
const Stack = createStackNavigator();
export default class AppStackContainer extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="My" component={My} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
页面之间如何跳转
上述例子中讲到了如何配置stackNavigator导航。页面配置完之后,让他们之间相互跳转才是重点。那么stackNavigator给我们提供了navigate、push、goback、popToTop等方法来完成页面跳转。上面例子中的Home页面代码如下:
import React, { Component } from 'react'
import { Text, Button, View, StyleSheet } from 'react-native'
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default class index extends Component {
goMyPage(){
const { navigation } = this.props;
navigation.navigate('My');
}
render() {
return (
<View style={styles.container}>
<Text> Home </Text>
<Button
title="去My page"
onPress={() => this.goMyPage()}
/>
</View>
)
}
}
由此可见,页面有一个button,其中点击事件中从props中获取到了navigation对象,这个对象就是NavigationContainer组件注册进来的属性。这也是为什么要用NavigationContainer进行包裹的原因。通过调用navigation对象navigate方法进行跳转,这个方法的第一个参数就是对应的导航Name属性。
navigate
标准的路由跳转方法,可以通过此方法进行随意的页面跳转,但是有一个原则,就是不能重复压栈。比如从Home跳转到了My,如果My页面还有一个按钮再次执行navigation.navigate('My');是不会再次跳转到一个新的My页面。
push
navigation.push('My')和navigation.navigate('My')在功能上有所类似,都是跳转到一个新页面,唯一不同的是,可以使用它进行重复的打开同一个页面。例如在My页面代码如下:
import React, { Component } from 'react'
import { Text, View, Button, StyleSheet } from 'react-native'
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default class index extends Component {
render() {
return (
<View style={styles.container}>
<Text> My </Text>
<Button
title="Go to My... again"
onPress={() => this.props.navigation.push('My')}
/>
<Button title="goback" onPress={()=> this.props.navigation.goBack()}></Button>
</View>
)
}
}
上述代码中的Go to My...again的按钮就可以重复的进入My页面。
goback(返回上一个页面)
使用navigation.goBack()就可以返回上一次进来的页面
popToTop(返回最前面的页面)
navigation.popToTop()就可以返回默认首页
页面之间如何传递参数
在常规的开发中,页面之间传递参数是最常见的操作,那么stackNaviator如何在页面之间传递参数呢?其实只需要两步就可以完整
- 在页面使用使用navigation.navigate('RouteName', { /* params go here */ })进行传递参数的设置。例如:
navigation.navigate('My', {
itemId: 86,
otherParam: 'anything you want here',
});
- 在接收页面的某个时机(mounted事件或者rander函数中)使用route进行接收,例如:
const { route } = this.props;//route也是被注册进来的参数如果这个参数params就可以获取传进来的参数
const { itemId , otherParam} = route.params;
console.log(itemId,otherParam)
设置Header的属性
stackNavigator最大的特点就是有一个header在顶部,那么如何设置它的属性呢?比如背景颜色、字体颜色、标题、以及右侧如何放置按钮等等。
设置标题
静态配置:
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'My home' }}
/>
</Stack.Navigator>
);
}
其他属性:
- title: string, 标题文字
- headerTitleAlign: 标题对齐方式,支持 left (Android 默认) / center (iOS 默认)
- headerTitleAllowFontScaling: 标题文字是否随系统文字大小缩放
- headerTintColor: 标题颜色
- headerTitleStyle: 自定义标题文字样式
- headerTitleContainerStyle: 自定义标题文字所在 View 容器的样式
- headerTitle: 标题,可直接设置文字,优先级高于 title;也可以设置为函数,返回一个组件,函数参数为 {allowFontScaling, style, children},这三个参数是由上面属性结合而来。
左侧按钮配置
- headerBackImage: 返回键,设置为一个函数,返回“返回键”组件,函数参数为 {tintColor:"标题颜色"}
- headerBackTitle: string 返回键右侧的返回文字
- headerTruncatedBackTitle: 返回文字过长,标题栏无法显示时的替代返回文字,默认: "Back"
- headerBackAllowFontScaling: 返回文字是否随系统文字大小缩放
- headerBackTitleStyle: 自定义返回文字样式
- headerBackTitleVisible: 是否显示返回文字,Android 默认 false,iOS 默认 true
- headerPressColorAndroid: Android 5 以上,点击返回按钮的水波纹颜色
- headerLeftContainerStyle: 自定义返回键和返回文字所在容器的样式
- headerLeft: 自定义 HeaderBackButton 左侧组件,指定为函数 或 RN组件,props 会传递上面的返回键和返回文字相关的设置
添加右侧按钮
- headerRight: 自定义标题栏右侧组件
- headerRightContainerStyle: 自定义右侧组件所在容器的样式
让我们在标题的右侧添加一个按钮(这是整个屏幕上最难触摸的位置之一,具体取决于手指和手机的大小,也是放置按钮的常规位置)。 例如:
function StackScreen() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
headerTitle: props => <LogoTitle {...props} />,
headerRight: () => (
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="#fff"
/>
),
}}
/>
</Stack.Navigator>
);
}
标题栏整体属性
- headerStatusBarHeight: 设置 statusBar 高度,Header 组件会 paddingTop 这个值以保证在刘海屏机型也可以正常使用,默认会由系统自动获取。
- headerStyle: 自定义标题栏样式
- headerTransparent: 标题栏是否透明,与在 headerStyle 直接设置 backgroundColor 的不同在于:这里设置透明,会使页面的 marginTop 为 0,此时需要定义 headerBackground 组件来遮挡。
- headerBackground: 标题栏背景组件,配合 headerTransparent 使用的,可以用来实现毛玻璃 Header 效果。
- safeAreaInsets: Header安全区域设置(针对刘海屏机型),默认情况下会自动设置,但也可以使用 {left, right, top, bottom} 手动设置,自定义设置注意考虑横竖屏的情况。
- headerShown: 是否显示标题栏
- header: 自定义标题栏组件,定义为函数,返回一个 RN 组件;设置该属性,即不使用默认 Header 了,以上属性失效。
动态更新 使用setOptions更新options
上述的所有属性都可以通过下面方法进行更新
<Button
title="Update the title"
onPress={() => this.props.navigation.setOptions({ title: 'Updated!' })}
/>
设置共享样式
通常希望在许多屏幕上以类似方式配置标题。 例如,您的公司品牌颜色可能是红色,因此您希望标题背景颜色为红色,而色调颜色为白色。 方便地,这些是我们在运行示例中使用的颜色,并且您会注意到,当导航到DetailsScreen时,颜色会恢复为默认值。 如果必须将选项标头样式属性从HomeScreen复制到DetailsScreen,并且对于我们在应用程序中使用的每个单个屏幕组件,这都不可怕吗? 幸运的是,我们没有。 相反,我们可以将配置上移到prop screenOptions下的堆栈导航器中。
例如:
function StackScreen() {
return (
<Stack.Navigator
screenOptions={{
headerStyle: {
backgroundColor: '#f4511e',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}
>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'My home' }}
/>
</Stack.Navigator>
);
}
Tab navigation 底部tab导航
安装
npm install @react-navigation/bottom-tabs