rn與原生相互傳值(二)
之前介紹過一種簡單的傳值方式,但是有侷限性,為此筆者有找到了一種方式。流程如下:
1,定義一個類:AnExampleReactPackage
public class AnExampleReactPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
//新增rn互動元件
modules.add(new RNBridge(reactContext)
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
2,在MainApplication註冊
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new AnExampleReactPackage()
);
}
3,寫公共的類RNBridge裡面有一些方法
public class RNBridge extends ReactContextBaseJavaModule {
private ReactContext mContext;
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
public RNBridge(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "RNBridge";
}
@ReactMethod
public void close() {
try {
Activity currentActivity = getCurrentActivity();
currentActivity.finish();
} catch (Exception e) {
}
}
//rn傳值,建立一個數組,可以把所有的引數都放到一起,rn介面直接獲取陣列相應的值即刻。例如,我的傳遞4個引數,uid,城市,數字,編號。對應的是0-3,rn直接獲取即可。
@ReactMethod
public void getDataFromIntent(ReadableArray params, Callback successBack, Callback erroBack) {
try {
Activity currentActivity = getCurrentActivity();
WritableArray writableArray = new WritableNativeArray(); //建立一個數組
writableArray.pushString(MainApplication.user_id); //新增引數
writableArray.pushString(MainApplication.city);
writableArray.pushString(MainApplication.num);
writableArray.pushString(MainApplication.dingdan + "");
successBack.invoke(writableArray);
} catch (Exception e) {
erroBack.invoke(e.getMessage());
}
}
//此方法用於rn介面簡單的跳轉到原生介面。
@ReactMethod
public void startActivityByString(String activityName) {
try {
Activity currentActivity = getCurrentActivity();
if (null != currentActivity) {
Class aimActivity = Class.forName(activityName);
Intent intent = new Intent(currentActivity, aimActivity);
currentActivity.startActivity(intent);
}
} catch (Exception e) {
throw new JSApplicationIllegalArgumentException(
"Could not open the activity : " + e.getMessage());
}
}
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
return constants;
}
@ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
/**
* RN向原生傳遞字串,用的場景不多
* @param s
*/
@ReactMethod
public void getStringFromReactNative(String s) {
Toast.makeText(mContext, s, Toast.LENGTH_SHORT).show();
}
/**
* RN向原生傳遞陣列 重點 提示:這是我自己的方法,不一定適用大家,下面有詳解。
* @param array
*/
@ReactMethod
public void getArrayFromRN(ReadableArray array,int duration) {
// Toast.makeText(getReactApplicationContext(), array.getString(0), duration).show();
// Toast.makeText(getReactApplicationContext(), array.getString(1), duration).show();
if (array.getString(3).equals("1")){
Intent intent = new Intent(getReactApplicationContext(), ALiPay.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("title",array.getString(0));
intent.putExtra("num",array.getString(1));
intent.putExtra("money",array.getString(2));
getReactApplicationContext().startActivity(intent);
}else {
Intent intent = new Intent(getReactApplicationContext(), WxPay.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("title",array.getString(0));
intent.putExtra("num",array.getString(1));
intent.putExtra("money",array.getString(2));
getReactApplicationContext().startActivity(intent);
}
}
@ReactMethod //啟動新的activity
public void startMain2() {
Intent intent = new Intent(getReactApplicationContext(), ALiPay.class);
main2Activity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("title",) //傳值
getReactApplicationContext().startActivity(intent);
}
}
4,傳值介面:HomeActivity就是A介面,TestActivity就是B介面,也就是rn介面,place就是標識
Intent intent = new Intent(HomeActivity.this, TestActivity.class);
intent.putExtra("place", city);
startActivity(intent);
5,rn介面:這個不必解釋
public class TestActivity extends ReactActivity {
@Override
protected String getMainComponentName() {
return "TestRN";
}
}
6,rn程式碼:關鍵程式碼(導包什麼的略過了)
componentDidMount() { //這是React的生命週期函式,會在介面載入完成後執行一次
RNBridge.getDataFromIntent(["place"], (successMsg) => {//通過place獲取陣列
let uid = successMsg[0];
let city = successMsg[1];
let flag = successMsg[2];
this.setState({ Text: successMsg }); //狀態改變的話重新繪製介面
console.log(successMsg[0])
console.log(successMsg[1])
console.log(successMsg[2])
this.setState({
uid: uid,
})
}, (erroMsg) => {
alert(erroMsg)
});
}
這就是原生向rn傳值的程式碼。下面是rn返回原生的方法。其實很簡單在 render() 有你的返回按鍵,在view了增加方法
<TouchableOpacity onPress={() => { RNBridge.close(); }}> //這個就是上面RNBridge裡的方法
<View style={styles.headLeftStyle}>
<Image source={backlogo} style={styles.backStyle}></Image> //圖片和風格,自己設定
</View>
</TouchableOpacity>
下面來講講rn向原生傳值。之前的準備工作已經做完,公共的方法在RNBridge裡面直接呼叫就行
RNBridge.getArrayFromRN(["標題", “第一個引數”,“第二個引數”, “第三個引數”], RNBridge.SHORT);
這裡的引數可以無限新增但是也和原生的方法裡面的陣列引數一一對應。否則取值不對。
大家可以把日誌打印出來,看看傳遞過來的數組裡的內容。
@ReactMethod
public void getArrayFromRN(ReadableArray array,int duration) {
// Toast.makeText(getReactApplicationContext(), array.getString(0), duration).show();
// Toast.makeText(getReactApplicationContext(), array.getString(1), duration).show();
Intent intent = new Intent(getReactApplicationContext(), ALiPay.class);//啟動一個新的activity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //詞句不可少
intent.putExtra("title",array.getString(0));
intent.putExtra("num",array.getString(1));
intent.putExtra("money",array.getString(2));
getReactApplicationContext().startActivity(intent);
}
完畢,不足之處,還望包涵!!!