集成react-navigation路由导航与避坑指南
文章目录
- 集成react-navigation路由导航与避坑指南
- 简介
- 集成流程
- 前情提要
- 调整结构
- settings
- 根目录build
- app下的build
- 其他build与settings的处理
- node_modules/@react-native/gradle-plugin
- settings
- build
- /gradle/wrapper/gradle-wrapper.properties
- /gradle/libs.version.toml
- 集成react-navigation
- yarn add
- 常见异常处理
- react-native-safe-area-context
- react-native-screens
- Activity中的packages新增
- 使用Navigation
- 启动
简介
作为一个RN新人,在简单了解了控件使用后,一个重头就在于路由跳转
React Native 官网指出现在主推的路由跳转方案是react-navigation,那么对于其他方案这边就不做了解了。
react-navigation官网
在集成这个东西的时候,踩过很多坑,业余时间吃了一个多礼拜,因此,这篇博文的目的在于简介react-navigation集成的流程,以及遇到各种问题的解决办法。
集成流程
前情提要
Android + RN 从零搭建 中简要介绍了如何将RN集成至已有的Android项目中。但是对于RN原生端的依赖都是通过在原生直接implementation的方式进行引用。
yarn add安装的包可能包含一些需要引入的依赖,如果希望原生也能够引用这些依赖,就需要原生工程引入这些包,使其同步参与build的sync。
这么说可能有些晦涩,就以上篇博文安装的@react-native来说,这里就存在我们需要sync的内容,让我们看一下目录。
很明显,看到了build和settings,那么在原生sync的时候,这个gradle-plugin也是需要参与sync的
调整结构
首先,明确说一点,新版AS构建项目的build和settings的方式不适合RN的集成,因为yarn add生成的包目前都是在build文件里写maven仓库的,如果在settings里声明仓库会出现冲突,sync无法通过。
所以针对新版AS生成的build和settings文件,需要对结构进行调整。
settings
settings一般是声明依赖的模块与地址,但是新版AS生成项目的时候,会将仓库信息也放进去。
所以针对settings的调整,需要将仓库移除。此外,上面提到要让gradle-plugin参与编译,因此要把gradle-plugin包也引入到原生工程中。
ok,那么咱们的settings就很纯粹了
rootProject.name = "RNDemo" // 这个是项目名称
include ':app' // 这个创建项目就有的,也不用管
includeBuild('../node_modules/@react-native/gradle-plugin') // 这个是你要加的,确保你的路径正确
根目录build
新版AS根目录的build只放了plugins闭包,内部存放必要插件,这么做的前提是因为settings里放了仓库资源。
但是新版AS这套的结构是用不了的,因此要还原成老版的样子
直接看代码吧,不多叭叭了
buildscript {
repositories {
需要的maven仓库,可以看上一篇博客
}
dependencies {
classpath('com.android.tools.build:gradle:7.4.2') // build编译插件版本
classpath('org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10') // kt插件版本
classpath("com.facebook.react:react-native-gradle-plugin") // 配置完这个后,引入react-android就不需要带版本了
}
}
allprojects {
repositories {
需要的maven仓库
}
}
app下的build
这个变动就不多了,结构没什么大的变化
首先需要引入插件:
id 'com.facebook.react'
其次,根据官网教程需要在最后添加如下语句,使得node_modules/@react-native-community/cli-platform-android/native_modules.gradle也会参与sync:
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
OK,到这里位置结构调整就算都完成了,但这样改完之后,能够成功sync吗?
那可不好说
其他build与settings的处理
上面引入了这么些通过yarn add进来的包,并使得他们的.gradle文件也参与sync,这就导致sync不过的可能性大大增加,基本上都是些版本不匹配,或者没有仓库下不到资源包之类的。具体哪个包出问题,到对应的包里去更改。
我这边目前的环境是gradle8.0.1, tool插件7.4.2, kotlin插件版本1.8.10
那么出错的包的版本,就都按照这个来!
node_modules/@react-native/gradle-plugin
注意: 高版本的.gradle文件,allowInsecureProtocol 变成了isAllowInsecureProtocol, url 变成 setUrl()
settings
pluginManagement {
repositories {
各种仓库
}
}
build
repositories {
各种仓库
}
/gradle/wrapper/gradle-wrapper.properties
distributionUrl = 你的gradle地址
/gradle/libs.version.toml
agp版本就用你tool插件的版本
OK,执行到这一步,你的Android工程应该是能正常编译运行的,连接了RN服务应该也是可以正常运行的。
集成react-navigation
这会终于是进入正题了,开始集成react-navigation
yarn add
虽然是跟着官网走,但是有个别包需要指定版本,否则跑出来会有找不到原生的一些类在UIManager中的问题
还有就是yarn add完之后,会把原本改动过的资源又还原回去,所以原本那些改动的build和settings还得再改下
- yarn add @react-navigation/native@next
- yarn add react-native-safe-area-context@3.0.5
- yarn add react-native-screens@3.13.1
- yarn add @react-navigation/native-stack@next
安装完后重新sync一下android工程,估计又会有报错来了,不过基本上也都是版本问题
常见异常处理
react-native-safe-area-context
build文件
repositories {
各种仓库
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10")
classpath("com.android.tools.build:gradle:7.4.2")
classpath("com.diffplug.spotless:spotless-plugin-gradle:6.11.0")
}
react-native-screens
build文件
externalNativeBuild闭包注掉,有报错
res 闭包里把/base去掉,否则ScreenStackHeaderConfig会报错
init 代码块里,R.attr.colorPrimary找不到,这个if语句注掉就行
Activity中的packages新增
当前列表为
listOf(MainReactPackage(), RNScreensPackage(), SafeAreaContextPackage())
不加这俩package,UIManager的那个RN报错还会有的
使用Navigation
这个就直接是官网荡的,能用就行
// In App.js in a new project
import * as React from 'react'
;import { View, Text } from 'react-native'
;import { createStaticNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
function HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
const RootStack = createNativeStackNavigator({
screens: {
Home: HomeScreen,
},
});
const Navigation = createStaticNavigation(RootStack);
export default function App() {
return <Navigation />;
}
还有入口index.js的componentFunc记得改一下,换成暴露出来的App
AppRegistry.registerComponent(
'MyReactNativeApp',
() => App,
);
启动
OK,集成结束,yarn start启动!
集成就ok了。后续的使用目前还没有计划写,大家先搁官网上瞅瞅,基础使用并不复杂。