|
背景: 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使用了,也希望能够帮助到你,谢谢阅览~ |