700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > RN与原生交互(一)——基本页面跳转

RN与原生交互(一)——基本页面跳转

时间:2024-04-10 19:46:41

相关推荐

RN与原生交互(一)——基本页面跳转

React Native(以下简称RN)开发app过程中大部分都可以在JS端完成,但是也有一些功能是需要原生端来完成的。这时RN与原生端就不可避免的需要进行交互,比如页面跳转和数据传递。本篇文章主要以RN——原生、原生——RN——原生为例来讲解如何进行基本的页面跳转操作。

关于页面跳转,我写了三个demo。这里发下地址:

RNAddNativeRNPushToNativeNativeJumpToRN

RNAddNativeRNPushToNative差不多,都是RN页面跳转到原生的实例,区别是一个RNAddNative使用了react-native-navigationRNPushToNative使用了react-navigation。在试过两种导航库之后,我更倾向于使用react-native-navigation,谁用谁知道。

NativeJumpToRN是原生页面跳转到RN,再从RN跳转到原生的示例。

在实际开发中,我认为RN页面(JS写的)和原生页面(iOS和Android写的)之间最好还是做到分离开来,通用页面还是用RN实现,各自需要定制化的、功能复杂的页面还是原生写。尽量不要搞RN和原生组件内嵌,毕竟写UI组件的话是相对比较简单的事,没必要在原生页面内嵌一个RN页面作为组件,或者RN页面内嵌一个原生组件。将两者分离开,有需要就直接页面间进行跳转,这样也方便处理。

RN——Native

如果你还没有创建原生项目,那直接react-native init创建一个RN项目,android和iOS的工程会自动给你创建好。android和iOS的工程都是可以拿来独立开发的,不会受RN的影响。如果已经有原生项目了,请自行搜索如何集成react native到现有原生项目,为了精简篇幅这里不多做赘述。

以RNPushToNative为例先来说明一下如何从RN跳转到原生页面。从RN跳转到原生,其实是在原生端创建Module类通过桥接的方式导出到JS端供JS代码调用原生端代码来实现的。

Android

Android分三步:

1. 定义Module类,继承ReactContextBaseJavaModule

在Module类中,重写getName方法声明Module类名称,创建我们自己的方法用来做页面跳转。

2. 定义Package类,实现接口ReactPackage

Package类需要实现createNativeModulescreateViewManagers两个方法。在createNativeModules中初始化Module类并添加到集合

3. 定义Application类,继承android的Application,并实现ReactApplication接口。

在getPackages方法中初始化Package类,并添加到集合。

RN项目创建的时候Application类就有了,不需要再创建。如果是集成到现有原生项目,就需要手动修改Application类。

Module类核心代码:

public class OpenNativeModule extends ReactContextBaseJavaModule {private ReactContext mReactContext;public OpenNativeModule(ReactApplicationContext context) {super(context);this.mReactContext = context;}@Overridepublic String getName() {return "OpenNativeModule";}@ReactMethodpublic void openNativeVC() {Intent intent = new Intent();intent.setClass(mReactContext, SettingsActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mReactContext.startActivity(intent);}}复制代码

Package类核心代码:

public class TestReactPackage implements ReactPackage {@Overridepublic List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {List<NativeModule> modules = new ArrayList<>();modules.add(new OpenNativeModule(reactContext));return modules;}@Overridepublic List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {return Collections.emptyList();}}复制代码

Application类核心代码:

@Overrideprotected List<ReactPackage> getPackages() {return Arrays.<ReactPackage>asList(new MainReactPackage(),new VectorIconsPackage(),new TestReactPackage());}复制代码

iOS

iOS端比Android就简单多了,只需要创建一个Module类,实现RCTBridgeModule协议就行了。

OpenNativeModule.h代码:

#import <Foundation/Foundation.h>#import <React/RCTBridgeModule.h>@interface OpenNativeModule : NSObject<RCTBridgeModule>@end复制代码

OpenNativeModule.m代码:

#import "OpenNativeModule.h"#import "AppDelegate.h"#import "NativeViewController.h"@implementation OpenNativeModuleRCT_EXPORT_MODULE();RCT_EXPORT_METHOD(openNativeVC) {dispatch_async(dispatch_get_main_queue(), ^{AppDelegate *delegate = (AppDelegate *)([UIApplication sharedApplication].delegate);UINavigationController *rootNav = delegate.navController;NativeViewController *nativeVC = [[NativeViewController alloc] init];[rootNav pushViewController:nativeVC animated:YES];});}@end复制代码

最后在RN端调用:

import React from 'react';import {View, Text, Button, NativeModules} from 'react-native';var nativeModule = NativeModules.OpenNativeModule;export default class HomeScreen extends ponent {render() {return (<View><Text>首页</Text><Button title={'跳转到原生页面'} onPress={() => {this.jumpToNativeView();}}/></View>)}jumpToNativeView() {nativeModule.openNativeVC();}}复制代码

Native——RN——Native

原生跳转到RN再由RN跳转到原生页面,这个示例可以参考NativeJumpToRN。RN到原生的跳转与上述原理相同,不同的是原生到RN的跳转。这个demo中我只是将原生项目启动后的初始页面由RN页面改为了原生页面,而原本的RN页面我将它内嵌在一个原生页面当中了。

对于Android来说,原本的启动页面是MainActivity,MainActivity就对应着RN页面。 我创建了一个LaunchActivity作为启动页面,在AndroidManifest.xml中将其设置为启动页。在LaunchActivity中添加一个button,设置点击跳转到MainActivity就完成了原生页面到RN的跳转,是不是很简单?

public class LaunchActivity extends AppCompatActivity {private Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_launch);button = (Button) findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(LaunchActivity.this, MainActivity.class);startActivity(intent);}});}}复制代码

iOS端也一样,RN页面的初始化是在AppDelegate中完成的,这里我们将window的rootViewController改为原生的UIViewControllerAppDelegate核心代码:

@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];_navController = [[UINavigationController alloc] initWithRootViewController:[[HomeViewController alloc] init]];self.window.rootViewController = _navController;[self.window makeKeyAndVisible];return YES;}@end复制代码

HomeViewController中创建一个button,点击button跳转到RNViewController

@implementation HomeViewController- (void)viewDidLoad {[super viewDidLoad];self.title = @"这是iOS原生页面";self.view.backgroundColor = [UIColor brownColor];UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 200, 50)];[button setTitle:@"点击跳转到RN页面" forState:UIControlStateNormal];[button addTarget:self action:@selector(onClickButton) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:button];}- (void)onClickButton {RNViewController *vc = [[RNViewController alloc] init];[self.navigationController pushViewController:vc animated:YES];}@end复制代码

AppDelegate中RN页面的初始化操作放到RNViewController中来:

@implementation RNViewController- (void)viewDidLoad {[super viewDidLoad];self.title = @"这是RN页面";NSURL *jsCodeLocation;jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocationmoduleName:@"NativeJumpToRN"initialProperties:nillaunchOptions:nil];rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];self.view = rootView;}复制代码

这样就完成了原生到RN的跳转。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。