android 使用原生UI组件

来源:互联网 发布:淘宝客户回访好评软件 编辑:程序博客网 时间:2024/06/05 18:57

在如今的App中,已经有成千上万的原生UI部件了——其中的一些是平台的一部分,另一些可能来自于一些第三方库,而且可能你自己还收藏了很多。React Native已经封装了大部分最常见的组件,譬如ScrollView和TextInput,但不可能封装全部组件。而且,说不定你曾经为自己以前的App还封装过一些组件,React Native肯定没法包含它们。幸运的是,在React Naitve应用程序中封装和植入已有的组件非常简单。

和原生模块向导一样,本向导也是一个相对高级的向导,我们假设你已经对Android编程颇有经验。本向导会引导你如何构建一个原生UI组件,带领你了解React Native核心库中ImageView组件的具体实现。

WebView样例

创建一个ViewManager的子类。实现createViewInstance方法。导出视图的属性设置器:使用@ReactProp(或@ReactPropGroup)注解。把这个视图管理类注册到应用程序包的createViewManagers里。实现JavaScript模块。

1.创建视图管理器

public class ReactWebViewManager extends SimpleViewManager<WebView> {    public static final String REACT_CLASS = "MGWebView";    @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");    }}

说明:
1.需要使用原生组件,不管是第三方组件还是系统原生组件,需要定义以上视图管理类(类名随便起),它继承自SimpleViewManager。WebView是这个视图管理类所管理的对象类型,这就是原生的UI组件视图。getName方法返回的名字会用于在JavaScript端引用这个原生视图类型,和JavaScript注册的名字相同。

2.通过@ReactProp(或@ReactPropGroup)注解来导出属性的设置方法,用于js中的属性传入参数,可以定义默认值。具体可以参考官网。

2.注册视图管理器

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());    }}

说明:
1.自定义以上类AppReactPackage(类名随便起),利用createViewManagers方法注册上面定义的视图管理器ReactWebViewManager

3.将这个AppReactPackage添加到ReactInstanceManager实例中去

 protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mReactRootView = new ReactRootView(this);        mReactInstanceManager = ReactInstanceManager.builder()                .setApplication(getApplication())                .setBundleAssetName("index.android.bundle")                .setJSMainModuleName("index.android")                .addPackage(new AppReactPackage())                .addPackage(new MainReactPackage())                .setUseDeveloperSupport(BuildConfig.DEBUG)                .setInitialLifecycleState(LifecycleState.RESUMED)                .build();        mReactRootView.startReactApplication(mReactInstanceManager, "reactandroid", null);        setContentView(mReactRootView);

说明:
1.首先会原生Android嵌入React Native
2.添加.addPackage(new AppReactPackage())

4.实现对应的JavaScript模块

'use strict';import { PropTypes } from 'react';import { requireNativeComponent, View } from 'react-native';var iface = {  name: 'MGWebView',  propTypes: {    url: PropTypes.string,    html: PropTypes.string,    ...View.propTypes,  },};module.exports = requireNativeComponent('MGWebView', iface);

5.##js中调用MGWebView

'use strict';import React from 'react';import {  AppRegistry,  StyleSheet,  Text,  View} from 'react-native';var MGWebView=require('./js/MGWebView');class HelloWorld extends React.Component {  render() {    return (   <View style={styles.container}>          <MGWebView  url="https://www.baidu.com" style={{fix:1}}></MGWebView>     </View>    )  }}var styles = StyleSheet.create({  container: {    flex: 1,    justifyContent: 'center',  },  hello: {    fontSize: 20,    textAlign: 'center',    margin: 10,  },});AppRegistry.registerComponent('reactandroid', () => HelloWorld);

添加事件

下面都是固定格式

1. 继承webview 进行重写

public class MGWebView extends WebView{    public MGWebView(Context context) {        super(context);    }    public MGWebView(Context context, AttributeSet attrs) {        super(context, attrs);    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int 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);    }}

2.webview.js

'use strict';import { PropTypes } from 'react';import { requireNativeComponent, View } from 'react-native';import React from '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 <MGWebView {...this.props} onChange={this._onChange} />;  }}WebView.propTypes = {    url: PropTypes.string,    html: PropTypes.string,    onScrollChange: PropTypes.func,    ...View.propTypes,};var MGWebView = requireNativeComponent('MGWebView', WebView,{    nativeOnly: {onChange: true}});module.exports = WebView

3.调用

import MGWebView from './js/WebView';class HelloWorld extends React.Component {  render() {    return (   <View style={styles.container}>          <MGWebView onScrollChange={this.onWebViewScroll} url="https://www.baidu.com" style={{width:400,height:400}}></MGWebView>     </View>    )  }}

4.结果

E/TAG: onScrollChangedE/TAG: onScrollChangedE/TAG: onScrollChangedE/TAG: onScrollChangedE/TAG: onScrollChangedE/TAG: onScrollChangedE/TAG: onScrollChangedE/TAG: onScrollChangedE/TAG: onScrollChangedE/TAG: onScrollChanged
1 0
原创粉丝点击