背景:
react native自带的view组件有时无法满足项目中一些特殊需求,或者性能、兼容性有待提升,这时往往就需要从原生入手,封装一套UI供RN上层使用。
原生UI封装步骤:
1.创建一个继承自ViewManager的子类:
这里注意到有三个可供继承:ViewManager、BaseViewManager(extend 前者)、SimpleViewManager(extend 前者),我们往往使用SimpleViewManager,它可以满足大多数的场景,因为它包含更多公共的属性,例如弹性布局、透明度、背景颜色等。
public class WebviewManager extends SimpleViewManager<View> {
    @Override
    public String getName() {
        return "WebView";
    }
}
2.实现 createViewInstance 方法:
    @Override
    protected View createViewInstance(ThemedReactContext reactContext) {
        this.mContext = reactContext;
       
        ll_Layout = (LinearLayout) LayoutInflater.from(mContext).inflate(R.layout.layout_webview,null);
        rl_layout = ll_Layout.findViewById(R.id.rl_layout);
        iv_back = ll_Layout.findViewById(R.id.iv_back);
        tv_title = ll_Layout.findViewById(R.id.tv_title);
        webView = ll_Layout.findViewById(R.id.webView);
        WebViewContance.settingWebView(webView,mContext);//设置webview属性
        webView.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                if(null != title){
                    tv_title.setText(title);
                }
            }
        });
        return ll_Layout;
    }

3.设置视图的属性:

使用@ReactProp(或@ReactPropGroup)注解:    
方法的第一个参数是指要修改属性的view对象,第二个参数是要设置的属性值,属性值支持的类型:boolean, int, float, double, String, Boolean, Integer, ReadableArray, ReadableMap,方法的返回值类型必须为void。
举例属性如下:(这里仅展示了部分属性,可根据实际项目需求预添加一些属性)

    //是否显示导航栏
    @ReactProp(name = "showNavigationBar")
    public void showNavigationBar(final View view, final boolean isShow) {
        if(isShow){
            rl_layout.setVisibility(View.VISIBLE);
        }else {
            rl_layout.setVisibility(View.GONE);
        }
    }

    //设置标题
    @ReactProp(name = "title")
    public void setTitle(final View view,final String title) {
        if(null != title){
            tv_title.setText(title);
        }
    }

    //设置加载的url
    @ReactProp(name = "url")
    public void setUrl(final View view,final String url) {
        if(url != null && url.trim().length()>0 ){
            webView.loadUrl(url);
        }
    }

4.注册viewManager:    

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

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

然后在自定义的Application中的getPackages方法中添加这个WebviewPackage
@Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
            new WebviewPackage()
      );
    }

5.在react native上层封装对应的WebView:

import React, {Component,} from 'react';
import {requireNativeComponent, StyleSheet, View,} from 'react-native';
import PropTypes from 'prop-types';
import {colors, dimens} from "../../resource";

const webView = {
    name:"WebView",
    propTypes:{
        "showNavigationBar":PropTypes.bool,
        "title":PropTypes.string,
        "url":PropTypes.string,
        ...View.propTypes
    }
}

const MyWebView = requireNativeComponent('WebView',webView,{
});

export default class WebView extends Component {
    render() {
        return (
            <MyWebView style={styles.webStyle}  {...this.props} />
        );
    }
}

6.引用这个组件使用即可。

到这里一个简单的原生的view就已经可以供RN使用了,也希望能够帮助到你,谢谢阅览~

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐