Android React native using native UI components

Source: Internet
Author: User
<span id="Label3"></p><p><p>Android React Native has encapsulated several common native components, such as ScrollView and TextInput, but not all of the original components of the system are encapsulated, so sometimes we have to do it ourselves. In order to be able to use native components that react native did not encapsulate for us, such as <strong>WebView</strong>, the official does not provide an android-side implementation, so let's wrap up the WebView now.</p></p><p><p>Previously wrote an article about Android React native using native modules, and using native UI components in a way that is very similar to using native Modules.</p></p><p><p>first, I need to inherit the generic class <strong>Simpleviewmanager</strong> , similar to the native module, which requires overriding the <strong>getName ()</strong> method, exposing the UI component name to the JavaScript layer, and then needing to rewrite <strong> The Createviewinstance</strong> method, in which we return an instance of the native UI component we need to use, is <strong>WebView</strong>. And then exposing some of the necessary properties to the JavaScript layer, for simplicity, We only expose two properties, one <strong>URL</strong>, one <strong>HTML</strong>, and once the JavaScript layer has a url, it loads a web page, And once the HTML is set, it will load the html, and the property is exposed to the use of annotations, the annotation set on the corresponding set method, and then the set method to deal with the UI updates, such as once the URL is set, the SetUrl will load the Web Page. In the end, that's how we viewmanager.</p></p><pre class="prettyprint prettyprinted" data-original-code="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"); }}" data-snippet-id="ext.329b12fe654599976cf9c9288406e94b" data-snippet-saved="false" data-csrftoken="YovcNaBu-lenjyfTe3r17RMPlzP81oURyVgs" data-codota-status="done"><code class=" hljs cs"><span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">class</span></span>Reactwebviewmanager extends Simpleviewmanager<webview> {<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span>Final String React_class =<span class="hljs-string"><span class="hljs-string">"rctwebview"</span></span>; @Override<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>String<span class="hljs-title"><span class="hljs-title">GetName</span></span>() {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>react_class; } @Override<span class="hljs-keyword"><span class="hljs-keyword">protected</span></span>WebView<span class="hljs-title"><span class="hljs-title">createviewinstance</span></span>(themedreactcontext Reactcontext) {WebView webview=<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>WebView (reactcontext); Webview.setwebviewclient (<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Webviewclient () {@Override<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>Boolean<span class="hljs-title"><span class="hljs-title">shouldoverrideurlloading</span></span>(WebView view, String Url) {view.loadurl (url);<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword">true</span></span>; } });<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>webView; } @ReactProp (name =<span class="hljs-string"><span class="hljs-string">"url"</span></span>)<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">SetUrl</span></span>(WebView view, @Nullable String Url) {LOG.E (<span class="hljs-string"><span class="hljs-string">"TAG"</span></span>,<span class="hljs-string"><span class="hljs-string">"seturl"</span></span>); View.loadurl (url); } @ReactProp (name =<span class="hljs-string"><span class="hljs-string">"html"</span></span>)<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">sethtml</span></span>(WebView view, @Nullable String html) {LOG.E (<span class="hljs-string"><span class="hljs-string">"TAG"</span></span>,<span class="hljs-string"><span class="hljs-string">"sethtml"</span></span>); View.loaddata (html,<span class="hljs-string"><span class="hljs-string">"text/html; Charset=utf-8 "</span></span>,<span class="hljs-string"><span class="hljs-string">"UTF-8"</span></span>); }}</code></pre><p><p>As with native modules, native UI components also need to be registered to implement the <strong>Reactpackage</strong> interface for WebView Registration.</p></p><pre class="prettyprint prettyprinted" data-original-code="public class AppReactPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Collections.emptyList();; } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Arrays.<ViewManager>asList( new ReactWebViewManager()); }}" data-snippet-id="ext.b8393c10894123c26f8f90dc93c90cac" data-snippet-saved="false" data-csrftoken="pAWMZxSf-LITk3G4glq3DgVmMEiqiHgeAN6k" data-codota-status="done"><code class=" hljs java"><span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">appreactpackage</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">reactpackage</span> {</span></span> <span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>List<nativemodule><span class="hljs-title"><span class="hljs-title">Createnativemodules</span></span>(reactapplicationcontext Reactcontext) {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>Collections.emptylist (); }<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>list<class<? Extends javascriptmodule>><span class="hljs-title"><span class="hljs-title">Createjsmodules</span></span>() {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>Collections.emptylist (); }<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>List<viewmanager><span class="hljs-title"><span class="hljs-title">createviewmanagers</span></span>(reactapplicationcontext Reactcontext) {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>Arrays.<viewmanager>aslist (<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Reactwebviewmanager ()); }}</code></pre><p><p>Add this <strong>reactpackage</strong> to the <strong>reactinstancemanager</strong> instance.</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs cs"> .addPackage(<span class="hljs-keyword">new</span> AppReactPackage())</code></pre></pre><p><p>Then create a new Webview.js file on the JavaScript layer. Enter the content below</p></p><pre class="prettyprint prettyprinted" data-original-code="‘use strict‘;var { requireNativeComponent,PropTypes } = require(‘react-native‘);var iface = { name: ‘WebView‘, propTypes: { url: PropTypes.string, html: PropTypes.string, },};module.exports = requireNativeComponent(‘RCTWebView‘, iface);" data-snippet-id="ext.aa786834a0b57de8ec4398fa5c17fa51" data-snippet-saved="false" data-csrftoken="VL7pbe1V-g9pNTN52rONbuBGpr5a04mYgXDQ" data-codota-status="done"><pre class="prettyprint prettyprinted" data-original-code="' use strict '; var {requirenativecomponent,proptypes} = Require (' react-native '); var iface = {name: ' WebView ', proptypes: {url:PropTypes.string, html:PropTypes.string, },};module.exports = requirenativecomponent (' rctwebview ', iface); " data-snippet-id=" Ext.aa786834a0b57de8ec4398fa5c17fa51 " data-snippet-saved=" false " data-csrftoken=" VL7PBE1V-G9PNTN52RONBUBGPR5A04MYGXDQ " data-codota-status=" Done "><code class=" hljs JavaScript "> <span class="hljs-pi"> ' use strict ' </span>; <span class="hljs-keyword">var </span> {requirenativecomponent,proptypes} = <span class="hljs-built_in">require </span> (<span class="hljs-string"> React-native ' </span>); <span class="hljs-keyword">var </span> iface = {name: <span class="hljs-string"> ' WebView ' </span>, proptypes: {url:p roptypes.string, html:PropTypes.string,},};module.exports = requirenativecomponent (<span class="hljs-string"> Rctwebview ' </span>, iface); </code> </pre></pre><p><p>As you can see, we just specify the type of the property Inside.</p></p><p><p>So far, you can already use this webview Component.</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs handlebars"><span class="xml"><span class="hljs-tag"><span class="php"><span class="hljs-keyword">var</span> WebView=<span class="hljs-keyword">require</span>(<span class="hljs-string">‘./WebView‘</span>);render: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span> <span class="hljs-keyword">return</span> ( <View style={styles.container}> <WebView url=<span class="hljs-string">"https://www.baidu.com"</span> style=</span></span></span><span class="hljs-expression">{{<span class="hljs-variable">width</span>:200,<span class="hljs-variable">height</span>:400}}</span><span class="xml"><span class="hljs-tag"><span class="php">></WebView> </View> ); }, </span></span></span></code></pre></pre><p><p>Here is just a simple load of Baidu home, there is a need to pay special attention to the width of the component must be set, otherwise you will not see this component. The final effect is as Follows.</p></p><p><p></p></p><p><p>This is just the basics of showing the original UI components, and more common are events, such as what we need to do with this WebView scrolling event at the JavaScript layer.</p></p><p><p>At this point we need to inherit the webview, rewrite the corresponding event, and then pass the event to the JavaScript layer.</p></p><pre class="prettyprint prettyprinted" data-original-code="public class RTCWebView extends WebView{ public RTCWebView(Context context) { super(context); } public RTCWebView(Context context, AttributeSet attrs) { super(context, attrs); } public RTCWebView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); Log.e("TAG","onScrollChanged"); WritableMap event = Arguments.createMap(); event.putInt("ScrollX", l); event.putInt("ScrollY", t); ReactContext reactContext = (ReactContext)getContext(); reactContext.getJSModule(RCTEventEmitter.class).receiveEvent( getId(), "topChange", event); }}" data-snippet-id="ext.d5f41ea0f3c749bd6ad60c834cdd71c4" data-snippet-saved="false" data-csrftoken="u6FvHhTk-BcTJg9sJ5CwAGa1moOHzHKTZCLc" data-codota-status="done"><code class=" hljs java"><span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">rtcwebview</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">WebView</span>{</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-title"><span class="hljs-title">Rtcwebview</span></span>(context Context) {<span class="hljs-keyword"><span class="hljs-keyword">Super</span></span>(context); }<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-title"><span class="hljs-title">Rtcwebview</span></span>(context context, AttributeSet Attrs) {<span class="hljs-keyword"><span class="hljs-keyword">Super</span></span>(context, attrs); }<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-title"><span class="hljs-title">Rtcwebview</span></span>(context context, AttributeSet attrs,<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Defstyleattr) {<span class="hljs-keyword"><span class="hljs-keyword">Super</span></span>(context, attrs, defstyleattr); }<span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword">protected</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">onscrollchanged</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>L<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>T<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>oldl,<span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Oldt) {<span class="hljs-keyword"><span class="hljs-keyword">Super</span></span>. onscrollchanged (l, t, oldl, oldt); LOG.E (<span class="hljs-string"><span class="hljs-string">"TAG"</span></span>,<span class="hljs-string"><span class="hljs-string">"onscrollchanged"</span></span>); Writablemap event = Arguments.createmap (); Event.putint (<span class="hljs-string"><span class="hljs-string">"scrollx"</span></span>, l); Event.putint (<span class="hljs-string"><span class="hljs-string">"scrolly"</span></span>, t); Reactcontext reactcontext = (reactcontext) getcontext (); Reactcontext.getjsmodule (rcteventemitter.class). receiveevent (getId (),<span class="hljs-string"><span class="hljs-string">"topchange"</span></span>, event); }}</code></pre><p><p>We rewrote the <strong>onscrollchanged</strong> method of the Scroll-time callback, constructed a <strong>writablemap</strong> object, passed Scrollx and scrolly in, and then called <strong> Reactcontext.getjsmodule (rcteventemitter.class). receiveevent (getId (), "topchange", event);</strong> Take the event to the JavaScript layer, noting that the <strong>Topchange</strong> corresponds to the <strong>onChange</strong> method of the JavaScript layer, which is mapped in <strong>uimanagermoduleconstants </strong>class.</p></p><p><p>Then we need to modify the <strong>createviewinstance</strong> method in reactwebviewmanager, and return the subclasses of our implementation, just like this</p></p><pre class="prettyprint prettyprinted" data-original-code="protected WebView createViewInstance(ThemedReactContext reactContext) { WebView webView= new RTCWebView(reactContext); webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); return webView; }" data-snippet-id="ext.70d2eba15fb830eaeb33a110c1099672" data-snippet-saved="false" data-csrftoken="eIXg8PgF-KfPCsn6eH20Gf5gmtU_z2_68DrU" data-codota-status="done"><code class=" hljs java"><code class=" hljs java"><span class="hljs-keyword">protected</span> WebView <span class="hljs-title">createViewInstance</span>(ThemedReactContext reactContext) { WebView webView= <span class="hljs-keyword">new</span> RTCWebView(reactContext); webView.setWebViewClient(<span class="hljs-keyword">new</span> WebViewClient(){ <span class="hljs-annotation">@Override</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">shouldOverrideUrlLoading</span>(WebView view, String url) { view.loadUrl(url); <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>; } }); <span class="hljs-keyword">return</span> webView; }</code></code></pre><p><p>The JavaScript layer also needs to be modified to a certain extent, the final code is as follows</p></p><pre class="prettyprint prettyprinted" data-original-code="‘use strict‘;var React = require(‘react-native‘);var { requireNativeComponent, PropTypes} = React;class WebView extends React.Component { constructor() { super(); this._onChange = this._onChange.bind(this); } _onChange(event: Event) { if (!this.props.onScrollChange) { return; } this.props.onScrollChange({ScrollX:event.nativeEvent.ScrollX,ScrollY:event.nativeEvent.ScrollY}); } render() { return <RCTWebView {...this.props} onChange={this._onChange} />; }}WebView.propTypes = { url: PropTypes.string, html: PropTypes.string, onScrollChange: PropTypes.func,};var RCTWebView = requireNativeComponent(‘RCTWebView‘, WebView,{ nativeOnly: {onChange: true}});module.exports = WebView" data-snippet-id="ext.d77348022d402d3fbda2fc1aea163b84" data-snippet-saved="false" data-csrftoken="M7VXVSiz-JsluEvZfqm_oyONV-uHimEkfOvM" data-codota-status="done"><code class=" hljs scala"><span class="hljs-string"><span class="hljs-string">' use strict '</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">var</span></span>React = require (<span class="hljs-string"><span class="hljs-string">' react-native '</span></span>);<span class="hljs-keyword"><span class="hljs-keyword">var</span></span>{requirenativecomponent, proptypes} = React;<span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">WebView</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>. <span class="hljs-title">Component</span> {</span></span>Constructor () {<span class="hljs-keyword"><span class="hljs-keyword">Super</span></span>();<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>. _onchange =<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>. _onchange.bind (<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>); } _onchange (event:event) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(!<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>. props.onscrollchange) {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>; }<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>. Props.onscrollchange ({scrollx:event.nativeevent.scrollx,scrolly:event.nativeevent.scrolly}); } render () {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span><rctwebview {...<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>. props} onchange={<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>. _onchange}/>; }}webview.proptypes = {url:PropTypes.string, html:PropTypes.string, onScrollChange:PropTypes.func,};<span class="hljs-keyword"><span class="hljs-keyword">var</span></span>Rctwebview = Requirenativecomponent (<span class="hljs-string"><span class="hljs-string">' Rctwebview '</span></span>, Webview,{nativeonly: {onChange:<span class="hljs-keyword"><span class="hljs-keyword">true</span></span>}}); module.exports = WebView</code></pre><p><p>Don't ask me why, because that's what the official document says, you just need to copy the code and make the changes, see document native UI components</p></p><p><p>Here need to pay attention to is <strong>function.bind (this)</strong> syntax, interested in their own to search online, this piece I also speak unclear, after all, not how to learn JavaScript and react, afraid of fraught. In the <strong>onChange</strong> function, We judge that if the property <strong>Onscrollchange</strong> is not set, it will return directly, otherwise it will call the Set Onscrollchange property value (the value is a function type). Pass two parameters passed into the Java layer into the function,<strong>{scrollx:event.nativeevent.scrollx,scrolly:event.nativeevent.scrolly}</strong></p></p><p><p>And then we're going to call</p></p><pre class="prettyprint"><code class=" hljs handlebars"><code class="hljs handlebars"><span class="xml"><span class="hljs-tag"><span class="php"><span class="hljs-keyword">var </span> webview=<span class="hljs-keyword">require </span> (<span class="hljs-string" ". webview ' < span>); render: <span class="hljs-function"><span class="hljs-keyword">function </span> <span class="hljs-params"> () </span> {</span> <span class="hljs-keyword">return </span> (<view Style={styles.container}><webview onscrollchange={this.onwebviewscroll} url= <span class="hljs-string"> "https://www.baidu.com" </span> style= </span> </span> </span> <span class="hljs-expression">{{<span class="hljs-variable">width </span>: 200,<span class="hljs-variable"> Height </span>: +}} </span> <span class="xml"><span class="hljs-tag"><span class="php">></webview></ View>);},onwebviewscroll:<span class="hljs-function"><span class="hljs-keyword">function </span> <span class=" Hljs-params " " (event) < span> {</span> console.log (event);}, </span> </span> </span> </span></span></code></code></pre><p><p>At this time wait for WebView loading processing, you swipe up and down, you will see the output of the console, as follows</p></p><p><p></p></p><p><p>The above is the whole process of using native UI components, we can see that react native has done a good package for us, we only need to write a small amount of code, we can use the native UI Components.</p></p> <p><p>Android React native using native UI components</p></p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.