w3ctech

React Native 扩展安卓原生模块

React Native (以下简称 RN)作为当下最为火热的前端框架,你只需要使用 React 和 JavaScropt 就可以编写出可以同时运行在 Android 和 ios 平台的 App。RN 提供了非常丰富的基础组件供开发者使用,但有时候 RN 提供的组件不足以满足我们的需求(尤其是 RN 版本比较老的情况下),我们便需要扩展原生模块。

在项目中,我们由于历史原因使用了0.30.0版本(1年前的版本)的 RN,该版本的 状态栏组件(StatusBar)的 barStyle不支持 dark-content (从0.41版本开始新加了这个枚举值),若将 barStyle 设置为 dark-conent ,则状态栏的图标会呈现出深色,这个属性对于在状态栏背景颜色为白色时设置沉浸式状态栏特别有用。Google 在Android6.0中提供了亮色状态栏模式,配置如下:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            activity.getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
   }

因此我们需要将上述代码暴露给前端使用,步骤如下:

1 .创建一个 StatusBarPlus 类继承 ReactContextBaseJavaModule

public class StatusBarPlus extends ReactContextBaseJavaModule {
    public StatusBarPlus(ReactApplicationContext reactContext) {
        super(reactContext);
    }

    @Override
    public String getName() {
        return "StatusBarPlus";
    }
    @ReactMethod
    public void setDarkContent () {
        final Activity activity = getCurrentActivity();
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
                    activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                }
            }
        });
    }
}

该类需要重写父类的 getName 方法,该方法需要返回一个字符串,模块封装完成后,前端需要根据该字符串访问该模块。用@ReactMethod注解修饰的方法即为暴露给前端的接口。

  1. 创建CustomerPackage 实现 ReactPackage
public class CustomerPackage implements ReactPackage {
    public CustomerPackage() {
        super();
    }

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

    @Override
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.EMPTY_LIST;
    }

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

主要实现 createNativeModules 方法内的逻辑,将我们封装的模块实例化之后添加到 list 中返回。其他两个方法若不需要添加逻辑,则需要将默认的 null 改为 Collections.EMPTY_LIST,否则会红屏。

  1. MainApplication中添加自定义Package
@Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
              new CustomerPackage()
      );
    }
  };

上述步骤完成之后,安卓端的工作便完成了,在前端我们可以通过一下代码调用刚刚的原生模块。

const StatusBarPlus  = NativeModules.StatusBarPlus;
StatusBarPlus.setDarkContent();

最后效果如下:

相关链接

w3ctech微信

扫码关注w3ctech微信公众号

共收到0条回复