React Native与原生交互之跳转
【摘要】 React Native(简称RN)开发的app大部分都可以在JS端完成,但是也有一些复杂的功能是需要原生端来完成的,或者是在原生项目中集成RN,此时RN与原生端就不可避免的需要进行交互,比如页面跳转和数据传递。关于RN与原生更深层次的调用原理,及如何自己封装RN的原生组件,可以参考《React Native移动开发实战》(ps:白皮版)。原生跳转RN是非常简单的,本文不做讲解,本文主要分析...
React Native(简称RN)开发的app大部分都可以在JS端完成,但是也有一些复杂的功能是需要原生端来完成的,或者是在原生项目中集成RN,此时RN与原生端就不可避免的需要进行交互,比如页面跳转和数据传递。
关于RN与原生更深层次的调用原理,及如何自己封装RN的原生组件,可以参考《React Native移动开发实战》(ps:白皮版)。原生跳转RN是非常简单的,本文不做讲解,本文主要分析其他的运用场景。
RN跳转原生页面
使用“react-native init”命令创建一个RN项目,新创建的项目包含了android和iOS的原生项目,如果有原生的代码可以在原生项目中编写,RN的代码则单独放到相应的JS文件中。从RN跳转到原生,其实是在原生端创建Module类通过桥接的方式导出到JS端供JS代码调用原生端代码来实现的。
跳转到Android原生
对于Android平台来说,要完成RN跳转到Android原生的功能,主要会涉及以下几个步骤:
1. 定义Module类,该类继承ReactContextBaseJavaModule
在Module类中,重写getName方法声明Module类名称,创建相关方法用来做页面跳转。
public class OpenNativeModule extends ReactContextBaseJavaModule {
private ReactContext mReactContext;
public OpenNativeModule(ReactApplicationContext context) {
super(context);
this.mReactContext = context;
}
@Override
public String getName() {
return "OpenNativeModule";
} //打开登录设置界面,用于给RN调用
@ReactMethod
public void openNativeVC() {
Intent intent = new Intent();
intent.setClass(mReactContext, SettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mReactContext.startActivity(intent);
}
}
2. 定义Package类,实现接口ReactPackage。
Package类需要实现createNativeModules和createViewManagers两个方法,在createNativeModules中初始化Module类并添加到集合。
public class TestReactPackage implements ReactPackage {
@Override
public List createNativeModules(
ReactApplicationContext reactContext) {
List modules = new ArrayList<>(); modules.add(new OpenNativeModule(reactContext)); return modules; } @Override public List createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } }
3. 定义Application类,继承android的Application,并实现ReactApplication接口。
每一个自定义的Package都需要添加到Application注册。在getPackages方法中初始化Package类,并添加到集合。
protected List getPackages() {
return Arrays.asList( new OpenNativePackage() ); }
跳转到iOS原生
相比Android,iOS的实现就相对简单得多,只需要创建一个Module类,实现RCTBridgeModule协议即可。涉及到的代码有:
OpenNativeModule.h
#import #import @interface OpenNativeModule : NSObject@end1234567
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中跳转的时候通过NativeModules.OpenNativeModule对象,然后就可以跳转了。例如:
import React from 'react';
import {View, Text, Button, NativeModules} from 'react-native';
var nativeModule = NativeModules.OpenNativeModule;
export default class HomeScreen extends React.Component {
render() { return (
{ this.jumpToNativeView(); }}/> )
}
jumpToNativeView() {
nativeModule.openNativeVC();
}
}
Native跳转到RN
Android
对于Android来说,原本的启动页面是MainActivity, MainActivity就对应着RN页面。 我创建了一个LaunchActivity作为启动页面,在AndroidManifest.xml中将其设置为启动页。在LaunchActivity中添加一个button,设置点击跳转到MainActivity就完成了原生页面到RN的跳转,是不是很简单?
public class LaunchActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launch);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(LaunchActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
}
ios
iOS端也一样,RN页面的初始化是在AppDelegate中完成的,这里我们将window的rootViewController改为原生的UIViewController。
@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];
}
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:jsCodeLocation
moduleName:@"NativeJumpToRN"
initialProperties:nil
launchOptions:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.view = rootView;
}
到此,原生页面向RN的跳转就算完成了。
本文转载自异步社区
原文链接:https://www.epubit.com/articleDetails?id=Nf5c2f4e7-1d1e-44f6-aa5e-6e4daf174bf9
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)