React Native开发React Native 专题React Native编程

ReactNative封装Android原生组件

2018-09-04  本文已影响18人  飞奔在路上

本篇以封装按钮组件为例.

Ready

在开始封装之前,希望你已经在本机搭建好React Native的Android运行环境.

Go

Android部分

  1. 创建一个原生的按钮,并为其添加映射事件以及按钮属性
package com.RCTButton;

import android.view.View;
import android.widget.Button;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;

import java.util.Map;

import javax.annotation.Nullable;

public class RCTButton extends SimpleViewManager<Button> {
    private ThemedReactContext mContext;
    // private static final String EVENT_NAME_ONCLICK_NATIVE = "onClick";
    private static final String EVENT_NAME_ONCLICK_NATIVE = "nativeClick";
    private static final String EVENT_NAME_ONCLICK_JS = "jsClick";

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

    @Override
    protected Button createViewInstance(ThemedReactContext reactContext) {
        this.mContext = reactContext;
        Button button = new Button(reactContext);
        return button;
    }

    @Override
    protected void addEventEmitters(final ThemedReactContext reactContext, Button view) {
        super.addEventEmitters(reactContext, view);
        view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                WritableMap data = Arguments.createMap();
                data.putString("msg", "点击按钮");
                reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
                        v.getId(),
                        EVENT_NAME_ONCLICK_NATIVE,
                        data
                );
            }
        });
    }

    /*
        name="text" : name对应的值是在js代码中使用该封装组件时的属性名。
         */
    @ReactProp(name = "text")
    public void setText(Button button, String text) {
        button.setText(text);
    }

    @Nullable
    @Override
    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.<String, Object>builder()
                .put(
                        EVENT_NAME_ONCLICK_NATIVE,
                        MapBuilder.of(
                                "registrationName",
                                EVENT_NAME_ONCLICK_JS))
                .build();

    }
}

  1. 注册该UI组件
package com.RCTButton;

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 RCTViewPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        return Collections.emptyList();

    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Arrays.<ViewManager>asList(new RCTButton());
    }

}

  1. 在MainApplication中注册
package com.batsoftapp;

import android.app.Application;

import com.RCTButton.RCTViewPackage;
import com.facebook.react.ReactApplication;
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 RCTViewPackage()
            );
        }

        @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 JS部分

'use strict';
import React, {PureComponent} from 'react';
import {
    View,
    Image,
    FlatList,
    StyleSheet,
    TouchableOpacity,
    requireNativeComponent
} from 'react-native';

import PropTypes from 'prop-types';

let rctButton = {
    name: 'RCTButton',
    propTypes: {
        text: PropTypes.string,
        ...View.propTypes
    }
}
let RCTButton = requireNativeComponent('RCTButton', rctButton);

export default class Example extends PureComponent {
 
  jsClick(event) {
        alert(event.nativeEvent.msg)
    }
  render(){
      <View style={[ThemeStyle.container}]}>
                <RCTButton style={{height: 50, width: 200}} text={'点击'} jsClick={(event) => this.jsClick(event)}/>
      </View>
  }
   
 
}

最终效果

Untitled1.gif
上一篇下一篇

猜你喜欢

热点阅读