加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

react-native node_modules 本地自定义组件实现

发布时间:2020-12-15 04:43:53 所属栏目:百科 来源:网络整理
导读:继续rn学习,由于rn在android端的组件还不足,之前使用了一个第三方的图片选择库。其本身也是个学习rn Native module的好例子。接下来看看如何根据自己需求来定义Native Module。这里以自定义一个dialog模块为例。 1. 一个module需要继承ReactContextBaseJav

继续rn学习,由于rn在android端的组件还不足,之前使用了一个第三方的图片选择库。其本身也是个学习rn Native module的好例子。接下来看看如何根据自己需求来定义Native Module。这里以自定义一个dialog模块为例。

1.  一个module需要继承ReactContextBaseJavaModule类,并实现其几个主要方法:
public class MyNativeModule extends ReactContextBaseJavaModule {
    final String NO_CANCEL = "NO_CANCEL";
    final String CAN_CANCEL = "CAN_CANCEL";
    private boolean CANCELABLE = false;
    private final Activity mMainActivity;
    private final ReactApplicationContext mReactContext;
    private Callback callback;
    private String title = "title";

    public MyNativeModule(ReactApplicationContext reactContext,Activity mainActivity){
        super(reactContext);
        this.mReactContext = reactContext;
        this.mMainActivity = mainActivity;
    }

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

    @Override
    public Map<String,Object> getConstants(){
        final Map<String,Object> constants = new HashMap<>();
        constants.put(NO_CANCEL,false);
        constants.put(CAN_CANCEL,true);
        return constants;
    }

    @ReactMethod
    public void show(ReadableMap params,Callback callBack){
        if(params.hasKey("cancelable") && params.getBoolean("cancelable"))
            CANCELABLE = true;
        else
            CANCELABLE = false;
        String t = params.getString("title");
        if(params.hasKey("title") && t != null)
            title = t;
        else{
            //no title
        }
        ReadableArray list = params.getArray("items");
        this.callback = callBack;
        String data[] = null;
        if(list != null) {
            data = new String[list.size()];
            int i = 0;
            for (; i < list.size(); i++) {
                data[i] = list.getString(i);
            }
        }
        ListDialog dialog = new ListDialog(mMainActivity,mMainActivity,data);
        dialog.show();
    }
}
首先是其getName方法,该方法返回组件的名称,需要与jsx中调用组件时名称一致。
其次,Map方法可以定义组件的一些静态数值,如Toast.LENGTH_SHORT。
还有就是自定义的调用方法,这类方法需要定义为 @ReactMethod。


2.  jsx到Java传输数据需要遵循一定规范:
    Boolean -> Bool
    Integer -> Number
    Double -> Number
    Float -> Number
    String -> String
    Callback -> function
    ReadableMap -> Object
    ReadableArray -> Array


3.   若需要回传数据,可以通过回调实现。又jsx中传入方法,callback接收并执行(注:*回调方法只能执行一次*):
callback.invoke(...params);
4.  实现需要弹出的dialog功能:
class ListDialog extends Dialog{
        private String[] itemData;
        private Activity mActivity;
        private ListView lv;
        private boolean hasCallBack = false;

        public ListDialog(Context context)
        {
            super(context);
        }
        public ListDialog(Context context,Activity activity){
            super(context);
            this.mActivity = activity;
        }
        public ListDialog(Context context,Activity activity,String [] data){
            super(context,R.style.dialog);
            this.mActivity = activity;
            this.itemData = data;

            View v = LayoutInflater.from(mActivity).inflate(R.layout.list_dialog,null,false);
            lv = (ListView) v.findViewById(R.id.list_dialog);
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(mActivity,R.layout.item_dialog_simple);
            for (int i = 0; i < itemData.length; i++)
            {
                adapter.add(itemData[i].toString());
            }
            lv.setAdapter(adapter);
            setContentView(v);

            lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent,View view,int position,long id) {
                    doCallBack(position);
                }
            });
            //getWindow().setWindowAnimations();
            boolean cancelable = false;
            setCanceledOnTouchOutside(CANCELABLE);
            setTitle(title);
            getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        }

        private void doCallBack(int position){
            if(!hasCallBack) {
                this.hasCallBack = true;
                WritableMap params = Arguments.createMap();
                params.putInt("itemID",position);
                callback.invoke(false,params);
                this.cancel();
            }
        }
    }

通过一个简单的内部类实现一个dialog展示。
5.  完成组件的注册:
public class MyModulePackage implements ReactPackage { private final Activity mMainActivity; private MyNativeModule myNativeModule; public MyModulePackage(Activity mMainActivity){ this.mMainActivity = mMainActivity; } @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext){ List<NativeModule> modules = new ArrayList<>(); modules.add(new MyNativeModule(reactApplicationContext,mMainActivity)); return modules; } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } }

主要实现其createNativeModules方法,加入自定义组件。
在MainActivity中添加该组件:

.addPackage(new MyModulePackage(MainActivity.this))
6.  最后在jsx中require一下该组件,就可以直接使用了。
var MyNativeModule = require('NativeModules').MyNativeModule;
...
MyNativeModule.show(params,(didCancel,response) => {
            if(!didCancel){
                if(response.itemID < params.items.length - 1)
                    ToastAndroid.show("showDialog -> " + response.itemID,ToastAndroid.SHORT);
                else
                    ToastAndroid.show("cancel",ToastAndroid.SHORT);
            }
        });

至此,就可以定义特定需要的组件了,也可以实现前面讲到的图片选择器。最后把demo发到git上。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读