安卓原生页面与react-native页面相互跳转实现
React-Native集成到现有的安卓项目请移步:
链接: https://blog.csdn.net/major_zhang/article/details/84645352
1.创建react-native项目
因为react-native更新得很快,使用react-native init命令创建项目会默认使用最新的react-native版本,这也导致了与之前一些api的不兼容。
我们可以使用下面的命令指定使用的react-native版本:
react-native init demo --verbose --version 0.57.7
2.原生页面跳转到react-native页面
使用android studio导入项目下的android子目录。由于使用命令react-native run-android默认会启动MainActivity作为第一个页面并且现在MainActivity会默认加载react-native页面,这里我们是想从MainActivity跳转到react-native页面。所以要改写一下MainActivity:
在MainActivity中添加两个按钮,一个跳转到react-native的主页面,另一个跳转到react-native的子页面。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rn);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,RNActivity.class));
}
});
findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,TestActivity.class));
}
});
}
}
然后我们创建RNActivity用于承载react-native的主页面,注意在getMainComponentName方法中返回的字符串就是在react-native中注册的组件名字。
public class RNActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript.
* This is used to schedule rendering of the component.
*/
@Override
protected String getMainComponentName() {
return "application";
}
}
在react-native注册的组件定义如下:AppRegistry.registerComponent方法的第一个参数是组件的名字,第二个参数是需要显示的组件。这里第二个参数我们使用了导航组件react-navigator来显示。
项目的index.js
import React, { Component } from 'react';
import { Text, AppRegistry } from 'react-native';
import {AppStackNavigator} from "./src/navigator/AppNavigator"
AppRegistry.registerComponent('application', () => AppStackNavigator);
然后使用命令react-native run-android将项目运行起来。
3.react-native页面跳转到原生页面
需要从react-native页面跳转到原生页面步实现方法是这样的:首先,在原生中创建一个继承ReactContextBaseJavaModule的类,重写getName方法并且添加一个供react-native调用的方法,该方法就是用于页面跳转。然后,创建一个继承ReactPackage的类,将继承于ReactContextBaseJavaModule的类的实列添加进去。最后,在MainApplication的getPackages方法中,添加继承于ReactPackage的类的实例。
代码如下:
MyIntentModule
package com.demo;
import android.app.Activity;
import android.content.Intent;
import android.text.TextUtils;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
public class MyIntentModule extends ReactContextBaseJavaModule {
public MyIntentModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "IntentMoudle";//这里定义的是该模块名字
}
@ReactMethod
public void startActivityFromJS(String name, String params){//该模块的方法
try{
Activity currentActivity = getCurrentActivity();
if(null!=currentActivity){
Class toActivity = Class.forName("com.demo."+name);
Intent intent = new Intent(currentActivity,toActivity);
intent.putExtra("params", params);
currentActivity.startActivity(intent);
}
}catch(Exception e){
throw new JSApplicationIllegalArgumentException(
"不能打开Activity : "+e.getMessage());
}
}
@ReactMethod
public void dataToJS(Callback successBack, Callback errorBack){
try{
Activity currentActivity = getCurrentActivity();
String result = currentActivity.getIntent().getStringExtra("data");
if (TextUtils.isEmpty(result)){
result = "没有数据";
}
successBack.invoke(result);
}catch (Exception e){
errorBack.invoke(e.getMessage());
}
}
}
MyReactPackage
package com.demo;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class MyReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new MyIntentModule(reactContext));
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
MainApplication
```java
package com.demo;
import android.app.Application;
import com.facebook.react.ReactApplication;
import org.devio.rn.splashscreen.SplashScreenReactPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import java.util.Arrays;
import java.util.List;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new SplashScreenReactPackage(),
new MyReactPackage()//将MyReactPackage实例添加进来
);
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
在react-native中调用,这个界面我写的示例比较多。其实使用起来很简单,先引入NativeModules,添加一个按钮,点击调用jumpNative方法。在方法中调用在原生定义的方法:NativeModules.IntentMoudle.startActivityFromJS(“MainActivity”, null);
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow
*/
import React, {Component} from 'react';
import {
AsyncStorage,
StyleSheet,
Image,
View,
Text,
TouchableOpacity,
ActivityIndicator,
DrawerLayoutAndroid,
NativeModules,//引入的模块
} from 'react-native';
export default class Home extends Component {
jumpNative(){
//调用原生方法
NativeModules.IntentMoudle.startActivityFromJS("MainActivity", null);
}
render() {
const {navigation} = this.props;
return (
<View>
<View style={styles.container}>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('TestPage');
}}>
<Text style={styles.bt_text}>
注册的子页面
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
this.jumpNative();
}}>
<Text style={styles.bt_text}>
跳转到原生页面
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('Page1', {name: '动态的title'});
}}>
<Text style={styles.bt_text}>
页面跳转
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('FlatListPage');
}}>
<Text style={styles.bt_text}>
列表页面
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('KeyboardAvoidingViewPage');
}}>
<Text style={styles.bt_text}>
键盘弹起自动伸缩
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('SomeComponent');
}}>
<Text style={styles.bt_text}>
一些组件
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('TextPage');
}}>
<Text style={styles.bt_text}>
文本标签
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('TouchablePage');
}}>
<Text style={styles.bt_text}>
Touchable
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('HookPage');
}}>
<Text style={styles.bt_text}>
生命周期
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('PlaceAnOrder');
}}>
<Text style={styles.bt_text}>
包车物流
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.bt} activeOpacity={0.5}
onPress={() => {
navigation.navigate('Component11');
}}>
<Text style={styles.bt_text}>
时间选择器
</Text>
</TouchableOpacity>
<ActivityIndicator size="large" color="#0000ff"/>
<View style={styles.container}>
<Image
style={{width: 180, height: 180}}
source={{uri: 'http://wx4.sinaimg.cn/bmiddle/78b88159gy1g8ryut3tdrg208l08lkgn.gif'}}
/>
<Image
style={{width: 180, height: 180}}
source={{uri: 'http://wx3.sinaimg.cn/bmiddle/006GJQvhly1g7qk0w0kyrg307e07e1hs.gif'}}
/>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
flexDirection: 'row',
flexWrap: 'wrap'
},
bt: {
width: 180,
height: 50,
backgroundColor: '#0af',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 5,
marginLeft: 5,
marginTop: 5,
},
bt_text: {
color: '#fff',
}
});
然后使用命令react-native run-android将项目运行起来。
完整的项目demo:
https://github.com/githubchl/ReactNativeDemo
注意,运行项目前。先npm install下载好项目依赖。然后打开android studio导入android目录下载好依赖,再使用react-native run-android运行项目。如果这篇博客确实帮助到你了,麻烦到github点个star。