博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RN与原生交互(一)——基本页面跳转
阅读量:6575 次
发布时间:2019-06-24

本文共 6459 字,大约阅读时间需要 21 分钟。

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

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

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到现有原生项目,为了精简篇幅这里不多做赘述。

以为例先来说明一下如何从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;    }    @Override    public String getName() {        return "OpenNativeModule";    }    @ReactMethod    public 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 {    @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(); }}复制代码

Application类核心代码:

@Override    protected List
getPackages() { return Arrays.
asList( new MainReactPackage(), new VectorIconsPackage(), new TestReactPackage() ); }复制代码

iOS

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

OpenNativeModule.h代码:

#import 
#import
@interface OpenNativeModule : NSObject
@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 React.Component {    render() {    return (      
首页

Native——RN——Native

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

对于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端也一样,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: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的跳转。

转载地址:http://dlgjo.baihongyu.com/

你可能感兴趣的文章
SQL SERVER 原来还可以这样玩 FOR XML PATH
查看>>
poj 2516 (费用流)
查看>>
PHP 访问类中的静态属性
查看>>
怀孕指南——北京
查看>>
getParameter
查看>>
CSS浮动与清浮动
查看>>
poj1006生理周期(中国剩余定理)
查看>>
HTML 标签说明
查看>>
锋利的jQuery-2--判断jQuery获取到的对象是否存在$().length
查看>>
20个使用手写字体的创意网站作品欣赏
查看>>
在Pycharm中使用GitHub
查看>>
linux 查询系统版本命令、查询端口号是否被占用命令
查看>>
java笔记八:IO流之字符流与字符缓冲流
查看>>
Docker 命令收集
查看>>
myeclipse注册码生成器
查看>>
BW数据源深入研究
查看>>
【转】接口测试总结
查看>>
怎样快速学好PHP技术之PHP学习方法总结
查看>>
这是歌手,马云
查看>>
泰国商家频繁被问是否支持手机付款,竟向游客放大招!
查看>>