ReactNative调用原生封装的代码和控件

1.RN调用Android原生封装的代码

首先在AS中新建一个类继承自ReactContextBaseJavaModule
代码如下:

public class TestNativeModule extends ReactContextBaseJavaModule {

    private ReactApplicationContext mContext;

    public TestNativeModule(@Nonnull ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
    }

    @Nonnull
    @Override
    public String getName() {
        //rn通过这个名字调用方法
        return "TestNativeModule";
    }
    //暴露给RN的方法
    //函数不能有返回值
    @ReactMethod
    public void rnCallAndroid(String msg) {
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
    }
}

AS新建TestReactPackage类继承自ReactPackage

public class TestReactPackage implements ReactPackage {

    @Nonnull
    @Override
    public List<NativeModule> createNativeModules(@Nonnull ReactApplicationContext reactContext) {
        List<NativeModule> list = new ArrayList<>();
        list.add(new TestNativeModule(reactContext));
        return list;
    }

    @Nonnull
    @Override
    public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

在MainApplication中getPackages方法中添加刚刚新建的TestReactPackage

	@Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
      		  ...
              new TestReactPackage(),
              ...
      );
    }

AS的内容就完成了,接下来在RN中调用,以一个单击事件为例,代码:

import {NativeModules} from "react-native";

...

<TouchableOpacity
    onPress={()=>{NativeModules.TestNativeModule.rnCallAndroid('调用成功!')}} >
    <Text>单击调用原生方法</Text>
</TouchableOpacity>

...

2.RN引用Android的控件以及传递参数

引用控件大多是引用一些自定义的控件或者媒体播放器等,首先需要新建一个类继承自SimpleViewManager,这里以引用原生Button为例:

public class ButtonManager extends SimpleViewManager<Button> implements LifecycleEventListener{

    public ThemedReactContext mContext;

    @Nonnull
    @Override
    public String getName() {
        return "ButtonManager";
    }

    @Nonnull
    @Override
    protected Button createViewInstance(@Nonnull ThemedReactContext reactContext) {
        this.mContext = reactContext;
        this.mContext.addLifecycleEventListener(this);
        final Button bn = new Button(reactContext);
        bn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 创建数据传递信使,类似于Android中的Bundle
                WritableMap data = Arguments.createMap();
                data.putString("msg","点击了bn");// key用于在RN中获取传递的数据

                mContext.getJSModule(RCTEventEmitter.class).receiveEvent(
                        bn.getId(), // RN层原生层根据id绑定在一起
                        "onClick", // 事件名称
                        data // 传递的数据
                );
            }
        });
        return bn;
    }

    /**  设置控件属性 rn传入*/
    @ReactProp(name = "text")
    public void setText(Button view, @Nullable String text) {
        view.setText(text);
    }
    /** 设置控件事件
     *  重写getExportedCustomDirectEventTypeConstants
     */
    @javax.annotation.Nullable
    @Override
    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.of("onClick",MapBuilder.of("registrationName", "onClick"));
    }

    @Override
    public void onHostResume() {

    }

    @Override
    public void onHostPause() {

    }

    @Override
    public void onHostDestroy() {

    }
}

然后和封装方法一样,需要新建package类集成ReactPackage不过这次是在createViewManagers方法中做修改:

public class ButtonPackage implements ReactPackage {
    @Nonnull
    @Override
    public List<NativeModule> createNativeModules(@Nonnull ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Nonnull
    @Override
    public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
        List<ViewManager> list = new ArrayList<>();
        list.add(new ButtonManager());
        return list;
    }
}

仍然需要在MainApplication中getPackages方法中添加:

	@Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
      		  ...
              new ButtonPackage(),
              ...
      );
    }

再reactnative中需要新建一个js文件将控件导出
AsButton:

import PropTypes from 'prop-types';
import {requireNativeComponent, ViewPropTypes} from 'react-native';

var iface = {
    name: 'ButtonManager',
    propTypes: {
        text: PropTypes.string,
        onClick:PropTypes.func,
        ...ViewPropTypes, // include the default view properties
    },
};

module.exports = requireNativeComponent('ButtonManager', iface,{ nativeOnly: { onClick: true }});

在需要引用的地方直接写标签即可:

<ButtonManager
                    style={{width:50,height:50}}
                    text={'成功'}
                    onClick={(event) => {
                        //接受AS中传递的参数
                        alert(event.nativeEvent.msg);
                    }}
                />

单击后的效果:
在这里插入图片描述
在AS中写buttonManager的时候没有设置宽高所以有点丑。。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值