目錄
- 1)搭建-原生集成rn
- 2)demo-包含搭建過程源碼
- 3)訪問原生側常量
- 4)訪問原生側方法
- 4.1)void無返回
- 4.2)有返回回調
- 5)原生啟動RN
- 5.1)RN獲取Activity傳遞的Intent數據
- 5.2)startActivityForResult返回Intent數據給Activity
- 6)RN啟動原生
- 6.1)Activity獲取RN傳遞的Intent數據
- 6.2)startActivityForResult返回Intent數據給RN
- 6.3)原生發送通知給RN
- 7)UI互嵌
- 7.1)原生界面內部分使用RN的界面
- 7.2)RN界面內部分使用原生的界面
1)搭建-原生集成rn
- react-native init 工程名
- copy原Android工程至Rn工程/android中,配置gradle
- app的gradle中加入
dependencies {
...
compile "com.facebook.react:react-native:+" // From node_modules.
}
- 項目gradle中加入
allprojects {
repositories {
...
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
...
}
- 配置權限
<uses-permission android:name="android.permission.INTERNET" />
<!-開發者菜單 可不用->
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
- 配置Application
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
//Debug模式,這個模式才能在JS里作調試
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
//返回帶有官方已有的package的集合
return Arrays.<ReactPackage>asList(
new MainReactPackage()
);
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
- Android 6.0(API level 23)或更高版本,開發版本中會要求打開懸浮窗(overlay)權限,生產版本則不要求,代碼可不用特別配置
- 新建Activity
public class FirstReactActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "FirstReactComponent"; //注冊的react組件名,RN里要用到
}
}
- 新建RN-Component
export default class FirstReactComponent extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
大家好,我是React界面release
</Text>
</View>
);
}
}
- 在RN的入口文件處注冊此Component,注意所有暴露給原生的Component都需要在入口文件處注冊。
~/index.android.js
import FirstReactComponent from './src/FirstReactComponent';
...
//暴露給原生使用
AppRegistry.registerComponent('FirstReactComponent', () => FirstReactComponent);
- 打開Packager服務
~/工程根目錄
npm start
ReactNative原生集成-Android
- 生產打release包
//創建keystore并配置gradle
signingConfigs {
release {
storeFile file("/Users/tugaofeng/tgf/study/rn/studyRn_Native/studyRn_Native_keystore")
storePassword "123456"
keyAlias "studyRn_Native_keystore"
keyPassword "123456"
}
}
buildTypes {
release {
...
signingConfig signingConfigs.release
}
}
//創建assets目錄 ./android/app/src/main/assets
//創建離線bundle和打包本地資源
react-native bundle --entry-file index.android.js --bundle-output ./android/app/src/main/assets/index.android.bundle --platform android --assets-dest ./android/app/src/main/res/ --dev false
//打簽名包即可
cd android && ./gradlew assembleRelease
//進入目錄安裝apk ./android/app/build/outputs/apk/release
adb install app-release.apk
2)demo
demo
Android快照
RN快照
- 創建一個原生模塊,繼承了ReactContextBaseJavaModule的Java類,內部可以實現一些JavaScript所需的功能
public class MyNativeBridgeModule extends ReactContextBaseJavaModule {
//定義全局回調,RN->原生 startActivityForResult 返回數據給之前的 RNActivity
private Callback secondActivityOnActivityResultCallback;
//定義全局rnContext
private ReactApplicationContext rnContext;
public MyNativeBridgeModule(ReactApplicationContext reactContext) {
super(reactContext);
rnContext = reactContext;
//定義監聽 RN->原生 startActivityForResult 返回數據給之前的 RNActivity
reactContext.addActivityEventListener(mActivityEventListener);
}
//重寫此方法,
//可在RN端通過React.NativeModules.NativeBridge標記使用此模塊
@Override
public String getName() {
return "MyNativeBridgeModule";
}
//此方法可被RN端訪問常量
@Nullable
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<String, Object>();
constants.put("Duration_Short", Toast.LENGTH_SHORT);
constants.put("Duration_Long", Toast.LENGTH_LONG);
constants.put("Native_Constants_A", "我是Native常量值");
return constants;
}
//@ReactMethod 此注解定義與RN端的調用方法
@ReactMethod
public void showToast(String msg, int duration) {
Toast.makeText(getReactApplicationContext(), msg, duration).show();
}
//方法的返回類型必須為void,跨端訪問為異步進行,需要返回值須寫回調
@ReactMethod
public void testCallBack(String msg, Callback successCB, Callback errorCB) {
try {
String result = msg + " ,但我被testCallBack方法修改了";
successCB.invoke(result);
} catch (Exception e) {
errorCB.invoke("異常:" + e.getMessage());
}
}
//實例:原生->RN 獲取之前Activity傳遞的數據
@ReactMethod
public void getDataFromIntent(Callback successCB, Callback errorCB) {
try {
Activity currentActivity = getCurrentActivity();
String intentString = currentActivity.getIntent().getStringExtra("intentData");
successCB.invoke(intentString);
} catch (Exception e) {
errorCB.invoke("異常:" + e.getMessage());
}
}
//實例:原生->RN startActivityForResult 返回數據給之前的Activity
@ReactMethod
public void finishActivityForResult(String msg) {
Activity currentActivity = getCurrentActivity();
Intent intent = new Intent();
intent.putExtra("intentData", msg);
currentActivity.setResult(Activity.RESULT_OK, intent);
currentActivity.finish();
}
//實例: RN->原生 打開新的Activity
//實際項目中可進行實際封裝
@ReactMethod
public void startNewActivityByString(String activityName, String data, Callback resultCB) {
Activity currentActivity = getCurrentActivity();
//此處采用隱式啟動,方便封裝。若顯示啟動,需要反射獲取class,或業務層上做kv映射。
Intent intent = new Intent("com.tgf.studyrn_native_android.SecondActivity");
//此處采用顯示啟動,需要反射
// Class aimActivity = null;
// try {
// aimActivity = Class.forName("com.tgf.studyrn_native_android.SecondActivity");
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
// Intent intent = new Intent(currentActivity,aimActivity);
//將回調函數賦值給全局變量,以便全局callback在mActivityEventListener中使用
secondActivityOnActivityResultCallback = resultCB;
currentActivity.startActivityForResult(intent, 1002);
}
//實例:RN->原生 startActivityForResult 返回數據給之前的 RNActivity
//方式一 : Callback回調
//方式二 : 發送通知
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case 1002:
//方式一 : Callback回調
// try {
// secondActivityOnActivityResultCallback.invoke(intent.getStringExtra("intentData"));
// }catch (Exception e){
// }
//方式二 : 發送通知
rnContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("notify", intent.getStringExtra("intentData"));
break;
}
}
};
}
- 創建自定義的ReactPackage,并在其中注冊第一步創建的原生模塊
public class MyReactPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList(); //return null編譯時會出錯,要改寫成返回空集合
}
//注冊Native模塊
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
//注冊自定義的Native模塊
modules.add(new MyNativeBridgeModule(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList(); //return null編譯時會出錯,要改寫成返回空集合
}
}
- 在工程Application中,加入自定義的ReactPackage
~/MainApplication.java
@Override
protected List<ReactPackage> getPackages() {
//返回帶有官方已有的package的集合
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new MyReactPackage() //加入自定義的Package類
);
}
- Android側的RNActivity類,繼承了ReactActivity
~/FirstReactActivity.java
public class FirstReactActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "FirstReactComponent"; //注冊的react組件名,一會在JS里要用到
}
//如果回調時不需要回到RN端處理,
//也可此處定義onActivityResult
//而不是在MyNativeBridgeModule中寫監聽
// @Override
// public void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
// switch (requestCode){
// case 1002:
// Toast.makeText(this,data.getStringExtra("intentData"),Toast.LENGTH_SHORT).show();
// break;
// }
// }
}
- RN側的示例代碼
~/FirstReactComponent.js
export default class FirstReactComponent extends Component {
constructor(props) {
super(props);
this.state = {
title:'大家好,我是React界面',
intentData:'',
};
}
//調用原生方法 showToast
_showToast = ()=>{
NativeModules.MyNativeBridgeModule.showToast('調用原生Toast',NativeModules.MyNativeBridgeModule.Duration_Short);
}
//調用原生方法 并獲取回調結果
_testCallback = ()=>{
NativeModules.MyNativeBridgeModule.testCallBack(this.state.title,
(result)=>{
console.log(result);
//獲取了回調結果,并修改了state的title
this.setState({
title:result,
})
},
(error)=>{
console.log(error);
}
);
}
//代碼層接管RN的物理返回鍵,
//return true不做RN層的返回處理
//交由Native層處理ActivityResult
_onBackAndroid = () => {
NativeModules.MyNativeBridgeModule.finishActivityForResult("回傳onActivityResult值1");
return true;
}
componentDidMount() {
//調用原生方法,獲取Activity的Intent數據
NativeModules.MyNativeBridgeModule.getDataFromIntent(
(result) => {
//獲取了回調結果,并修改了state的title
this.setState({
intentData:result,
})
},
(error) => {
console.log(error);
}
);
//注冊Android物理返回鍵監聽
BackHandler.addEventListener('hardwareBackPress', this._onBackAndroid);
//注冊通知
this.subscription = DeviceEventEmitter.addListener('notify',(result)=>{
NativeModules.MyNativeBridgeModule.showToast(result,NativeModules.MyNativeBridgeModule.Duration_Short);
});
}
componentWillUnmount() {
//解綁Android物理返回鍵監聽
BackHandler.removeEventListener('hardwareBackPress', this._onBackAndroid);
// 移除通知
this.subscription.remove();
}
//調用原生方法,打開新的Activity,并可傳遞數據
_startNewActivity = ()=>{
NativeModules.MyNativeBridgeModule.startNewActivityByString("","",(result)=>{
NativeModules.MyNativeBridgeModule.showToast(result,NativeModules.MyNativeBridgeModule.Duration_Short);
});
}
render() {
//獲取原生常量值
const Native_Constants_A = NativeModules.MyNativeBridgeModule.Native_Constants_A;
return (
<View style={styles.container}>
<Text style={styles.welcome}>
{this.state.title}
</Text>
<Text style={styles.instructions}>
{this.state.intentData}
</Text>
<Text style={styles.instructions}>
{Native_Constants_A}
</Text>
<TouchableOpacity onPress={this._showToast} style={styles.button}>
<Text style={styles.instructions}>
點我調用原生Toast
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this._testCallback} style={styles.button}>
<Text style={styles.instructions}>
點我調用原生方法并獲取回調結果
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this._startNewActivity} style={styles.button}>
<Text style={styles.instructions}>
點我打開原生Activity(RN->Native)
</Text>
</TouchableOpacity>
</View>
);
}
}
//暴露給原生使用
AppRegistry.registerComponent('FirstReactComponent', () => FirstReactComponent);
3)訪問原生側常量
在自定義的原生模塊中,通過重寫getConstants()即可被RN訪問常量。
RN通過NativeModules.MyNativeBridgeModule.Native_Constants_A;即可調用。
~/MyNativeBridgeModule.java
//此方法可被RN端訪問常量
@Nullable
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<String, Object>();
constants.put("Duration_Short", Toast.LENGTH_SHORT);
constants.put("Duration_Long", Toast.LENGTH_LONG);
constants.put("Native_Constants_A", "我是Native常量值");
return constants;
}
~/FirstReactComponent.js
NativeModules.MyNativeBridgeModule.Native_Constants_A;
4)訪問原生側方法
原生通過注解 @ReactMethod暴露
4.1)void無返回
//@ReactMethod 此注解定義與RN端的調用方法
@ReactMethod
public void showToast(String msg, int duration) {
Toast.makeText(getReactApplicationContext(), msg, duration).show();
}
//調用原生方法 showToast
_showToast = ()=>{
NativeModules.MyNativeBridgeModule.showToast('調用原生Toast',NativeModules.MyNativeBridgeModule.Duration_Short);
}
4.2)有返回回調
由于跨端的訪問都是異步進行,可以通過Callback回調函數獲取返回值
//方法的返回類型必須為void,跨端訪問為異步進行,需要返回值須寫回調
@ReactMethod
public void testCallBack(String msg, Callback successCB, Callback errorCB) {
try {
String result = msg + " ,但我被testCallBack方法修改了";
successCB.invoke(result);
} catch (Exception e) {
errorCB.invoke("異常:" + e.getMessage());
}
}
//調用原生方法 并獲取回調結果
_testCallback = ()=>{
NativeModules.MyNativeBridgeModule.testCallBack(this.state.title,
(result)=>{
console.log(result);
//獲取了回調結果,并修改了state的title
this.setState({
title:result,
})
},
(error)=>{
console.log(error);
}
);
}
5)原生啟動RN
Intent intent = new Intent(this,FirstReactActivity.class);
intent.putExtra("intentData","我是MainActivity傳遞的intentData");
startActivityForResult(intent,1001);
5.1)RN獲取Activity傳遞的Intent數據
//實例:原生->RN 獲取之前Activity傳遞的數據
@ReactMethod
public void getDataFromIntent(Callback successCB, Callback errorCB) {
try {
Activity currentActivity = getCurrentActivity();
String intentString = currentActivity.getIntent().getStringExtra("intentData");
successCB.invoke(intentString);
} catch (Exception e) {
errorCB.invoke("異常:" + e.getMessage());
}
}
componentDidMount() {
//調用原生方法,獲取Activity的Intent數據
NativeModules.MyNativeBridgeModule.getDataFromIntent(
(result) => {
//獲取了回調結果,并修改了state的title
this.setState({
intentData:result,
})
},
(error) => {
console.log(error);
}
);
}
5.2)startActivityForResult返回Intent數據給Activity
//實例:原生->RN startActivityForResult 返回數據給之前的Activity
@ReactMethod
public void finishActivityForResult(String msg) {
Activity currentActivity = getCurrentActivity();
Intent intent = new Intent();
intent.putExtra("intentData", msg);
currentActivity.setResult(Activity.RESULT_OK, intent);
currentActivity.finish();
}
通過接管返回操作來優先調用@ReactMethod方法。若在componentWillUnmount()中處理會導致Activity優先接收到onActivityResult,而后進入@ReactMethod方法。
//代碼層接管RN的物理返回鍵,
//return true不做RN層的返回處理
//交由Native層處理ActivityResult
_onBackAndroid = () => {
NativeModules.MyNativeBridgeModule.finishActivityForResult("回傳onActivityResult值1");
return true;
}
componentDidMount() {
//注冊Android物理返回鍵監聽
BackHandler.addEventListener('hardwareBackPress', this._onBackAndroid);
}
componentWillUnmount() {
//解綁Android物理返回鍵監聽
BackHandler.removeEventListener('hardwareBackPress', this._onBackAndroid);
}
6)RN啟動原生
RN啟動原生可采用隱式或顯示(須反射)啟動
6.1)Activity獲取RN傳遞的Intent數據
//實例: RN->原生 打開新的Activity
//實際項目中可進行實際封裝
@ReactMethod
public void startNewActivityByString(String activityName, String data, Callback resultCB) {
Activity currentActivity = getCurrentActivity();
//此處采用隱式啟動,方便封裝。若顯示啟動,需要反射獲取class,或業務層上做kv映射。
Intent intent = new Intent("com.tgf.studyrn_native_android.SecondActivity");
//此處采用顯示啟動,需要反射
// Class aimActivity = null;
// try {
// aimActivity = Class.forName("com.tgf.studyrn_native_android.SecondActivity");
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
// Intent intent = new Intent(currentActivity,aimActivity);
//將回調函數賦值給全局變量,以便全局callback在mActivityEventListener中使用
secondActivityOnActivityResultCallback = resultCB;
currentActivity.startActivityForResult(intent, 1002);
}
//調用原生方法,打開新的Activity,并可傳遞數據
_startNewActivity = ()=>{
NativeModules.MyNativeBridgeModule.startNewActivityByString("","",(result)=>{
NativeModules.MyNativeBridgeModule.showToast(result,NativeModules.MyNativeBridgeModule.Duration_Short);
});
}
6.2)startActivityForResult返回Intent數據給RN
須定義監聽BaseActivityEventListener,通過其onActivityResult來獲取。
方式一:全局變量secondActivityOnActivityResultCallback發出回調給RN
方式二:rnContext.getJSModule發出通知給RN
//定義全局回調,RN->原生 startActivityForResult 返回數據給之前的 RNActivity
private Callback secondActivityOnActivityResultCallback;
//定義全局rnContext
private ReactApplicationContext rnContext;
public MyNativeBridgeModule(ReactApplicationContext reactContext) {
super(reactContext);
rnContext = reactContext;
//定義監聽 RN->原生 startActivityForResult 返回數據給之前的 RNActivity
reactContext.addActivityEventListener(mActivityEventListener);
}
//實例:RN->原生 startActivityForResult 返回數據給之前的 RNActivity
//方式一 : Callback回調
//方式二 : 發送通知
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case 1002:
//方式一 : Callback回調
//try {
//secondActivityOnActivityResultCallback.invoke(intent.getStringExtra("intentData"));
//}catch (Exception e){
//}
//方式二 : 發送通知
rnContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("notify", intent.getStringExtra("intentData"));
break;
}
}
};
6.3)原生發送通知給RN
發送部分參見6.2
componentDidMount() {
//注冊通知
this.subscription = DeviceEventEmitter.addListener('notify',(result)=>{
NativeModules.MyNativeBridgeModule.showToast(result,NativeModules.MyNativeBridgeModule.Duration_Short);
});
}
componentWillUnmount() {
// 移除通知
this.subscription.remove();
}
7)UI互嵌
7.1)原生界面內部分使用RN的界面
原生界面內部分使用RN的界面
*實例:在原生Activity中部分使用RN的UI,應將Rn的組件作為Android中的fragment來使用
- 新建MyReactFragment繼承Fragment
public abstract class MyReactFragment extends Fragment {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
//返回RN 的 Appregistry注冊的組件名字.
public abstract String getMainComponentName();
@Override
public void onAttach(Context context) {
super.onAttach(context);
mReactRootView = new ReactRootView(context);
mReactInstanceManager =
((MainApplication) getActivity().getApplication())
.getReactNativeHost()
.getReactInstanceManager();
}
//這里改寫根View為ReactRootView,因此繼承此類的fragment實現`getMainComponentName`即可
@Override
public ReactRootView onCreateView(LayoutInflater inflater, ViewGroup group, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
return mReactRootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mReactRootView.startReactApplication(
mReactInstanceManager,
getMainComponentName(),
null
);
}
}
- 新建ThirdReactFragment繼承第一步創建的MyReactFragment
public class ThirdReactFragment extends MyReactFragment {
@Override
public String getMainComponentName() {
//對應RN 的 Appregistry注冊的組件名字.
return "ThirdReactComponent";
}
}
- RN側創建ThirdReactComponent組件給原生側使用
export default class ThirdReactComponent extends Component {
//調用原生方法 showToast
_showToast = ()=>{
NativeModules.MyNativeBridgeModule.showToast('調用原生Toast',NativeModules.MyNativeBridgeModule.Duration_Short);
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this._showToast}>
<Text>大家好 我是React的UI,我準備嵌入到原生UI里</Text>
</TouchableOpacity>
</View>
);
}
}
//暴露給原生使用
AppRegistry.registerComponent('ThirdReactComponent', () => ThirdReactComponent);
- Android創建Activity
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.tgf.studyrn_native_android.SecondActivity">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="100dp"></FrameLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_centerInParent="true"
android:text="大家好,我是原生SecondActivity"/>
</LinearLayout>
public class SecondActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
private ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mReactInstanceManager =
((MainApplication) getApplication()).getReactNativeHost().getReactInstanceManager();
Fragment viewFragment = new ThirdReactFragment();
getSupportFragmentManager().beginTransaction().add(R.id.container,viewFragment).commit();
}
//掛載的Activity還需要實現DefaultHardwareBackBtnHandler接口,以保證RN的生命周期=========
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause();
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
}
7.2)RN界面內部分使用原生的界面
RN界面內部分使用原生的界面
*示例:在RN的界面中部分使用原生的TextView組件。
- 創建一個視圖管理類MyTextViewManager
public class MyTextViewManager extends SimpleViewManager<ReactTextView> {
@Override
public String getName() {
//方法返回的名字會用于在JavaScript端引用這個原生視圖
return "MyTextViewManager";
}
@Override
protected ReactTextView createViewInstance(ThemedReactContext reactContext) {
ReactTextView textView = new ReactTextView(reactContext);
return textView;
}
//@ReactProp
//(name = "text") 這個參數指定了對應屬性在JavaScript端的名字
@ReactProp(name = "text")
public void setText(ReactTextView textView,String text){
textView.setText(text);
}
}
- 在MyReactPackage注冊第一步新建的ViewManager
~/MyReactPackage.java
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
List<ViewManager> modules = new ArrayList<>();
modules.add(new MyTextViewManager()); //注冊自定義的ViewManager模塊
return modules;
}
- 實現對應的JavaScript模塊
import { PropTypes } from 'react';
import { requireNativeComponent, View } from 'react-native';
var myTextView = {
name: 'MyTextView',
propTypes: {
text:PropTypes.string,
...View.propTypes //包含默認的View的屬性,如果沒有這句會報‘has no propType for native prop’錯誤
},
};
module.exports = requireNativeComponent('MyTextViewManager', myTextView);
- 在Rn組件中引用此JS模塊
import MyTextView from './MyTextView';
export default class SecondReactComponent extends Component {
constructor(props) {
super(props);
this.state = {
title:'大家好,我是SecondReactComponent界面',
};
}
render() {
return (
<View style={styles.container}>
<MyTextView
style={styles.welcome}
text={'大家好,我使用了原生自定義的MyTextView組件'}/>
<Text>{this.state.title}</Text>
</View>
);
}
}
//暴露給原生使用
AppRegistry.registerComponent('SecondReactComponent', () => SecondReactComponent);
- 新建SecondReactActivity繼承ReactActivity
public class SecondReactActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "SecondReactComponent"; //注冊的react組件名,一會在JS里要用到
}
}
參考資料
官網
https://github.com/ipk2015/RN-Resource-ipk/tree/master/react-native-docs