在如今的App中,已經有成千上萬的原生UI部件了——其中的一些是平台的一部分,另一些可能來自於一些第三方庫,而且可能你自己還收藏了很多。React Native已經封裝了大部分最常見的組件,譬如ScrollView和TextInput,但不可能封裝全部組件。而且,說不定你曾經為自己以前的App還封裝過一些組件,React Native肯定沒法包含它們。幸運的是,在React Naitve應用程序中封裝和植入已有的組件非常簡單。
比如WebView,官方並沒有提供Android端的實現,那么我們現在就動手封裝一下WebView。
首先,我需要繼承SimpleViewManager這個泛型類,和原生模塊類似,需要重寫getName()方法,將UI組件名稱暴露給javascript層,接着需要重寫createViewInstance方法,在里面返回我們需要使用的原生UI組件的實例,這里就是WebView。然后就是暴露一些必要屬性給javascript層,為了簡單起見,我們這里只暴露兩個屬性,一個是url,一個是html,一旦javascript層設置了url,就會加載一個網頁,而一旦設置了html,則會去加載這段html,而屬性的暴露是使用注解,將注解設置在對應的set方法上,之后再set方法中處理UI的更新,比如一旦設置了url,在setUrl里面就要加載網頁。
類ReactWebViewManager,首先注意導包
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.views.image.ReactImageView;
import com.facebook.react.views.image.ImageResizeMode;
import java.util.Arrays;
import java.util.List;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.support.annotation.Nullable;
有個地方要注意一下,這里導包ReactProp,現在最新的ReactProp包是
import com.facebook.react.uimanager.annotations.ReactProp;
以前是
import com.facebook.react.uimanager.ReactProp;
剩下的主要代碼
public class ReactWebViewManager extends SimpleViewManager<WebView> { public static final String REACT_CLASS = "RCTWebView"; @Override public String getName() { return REACT_CLASS; } @Override protected WebView createViewInstance(ThemedReactContext reactContext) { WebView webView= new WebView(reactContext); webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); return webView; } @ReactProp(name = "url") public void setUrl(WebView view,@Nullable String url) { Log.e("TAG", "setUrl"); view.loadUrl(url); } @ReactProp(name = "html") public void setHtml(WebView view,@Nullable String html) { Log.e("TAG", "setHtml"); view.loadData(html, "text/html; charset=utf-8", "UTF-8"); } }
另外和原生模塊一樣,原生UI組件也需要進行注冊,實現ReactPackage接口,進行WebView的注冊。
類AnExampleReactPakge
將這個ReactPackage添加到ReactInstanceManager實例中去,在MainActivty中
然后在javascript層新建一個WebView.js文件。輸入下面的內容
'use strict'; import React, { PropTypes } from 'react'; import{ requireNativeComponent, } from 'react-native'; // var { requireNativeComponent,PropTypes } = require('react-native'); var iface = { name: 'WebView', propTypes: { url: PropTypes.string, html: PropTypes.string, }, }; module.exports = requireNativeComponent('RCTWebView', iface,{ nativeOnly:{ "testID": true, 'renderToHardwareTextureAndroid': true, 'accessibilityComponentType': true, 'accessibilityLabel': true, 'importantForAccessibility': true, 'accessibilityLiveRegion': true, 'onLayout':true, } });
到目前為止,你已經可以使用這個WebView組件了。
var WebView=require('./WebView'); render: function() { return ( <View style={styles.container}> <WebView url="https://www.baidu.com" style={{width:200,height:400}}></WebView> </View> ); },