React-Native系列Android——自定义View组件开发
2016-03-23 22:53
821 查看
React-Native是由ReactJS发展而来,继承了其JavaScript XML(简称JSX)和组件化等特性。JSX是一种XML语言,用于视图层级搭建。而组件化是一种设计思想,具有易于维护组合和便于扩展等优点,React-Native中无论是原生Java层,还是JS层,都遵循了这种思想。
在Android原生Java端的组件分为两种类型:视图组件(View)和功能组件(Module),React-Native官方为开发者提供了大量的常用组件,位于com.facebook.react.views包和com.facebook.react.modules包下面,基本覆盖了所有类型的组件,包括文本,输入框,图片等。
本文GradientColorView(颜色渐变视图)为例,演示如何自定义一个原生View组件,并在JS中调用。
代码非常简单,自定义一个普通View,并提供两个控制渐变颜色的方法setStartColor和setEndColor,然后再onDraw方法里面绘制在画布上。
这里需要实现两个简单的方法getName和createViewInstance,前者用来映射JS中的组件(后面讲到),后者用来创建View实例。
同时需要提供两个被注入的方法setStartColor和setEndColor,必须使用ReactProp注解,name值与JS中属性名保持一致。
除了必要的MainReactPackage之外,注册了一个匿名内部类ReactPackage,包含了GradientColorViewManager。这样GradientColorViewManager的注册就完成了。
接下来需要开发JS层对应的组件了。
前面说过,Javascript层也遵循了组件化设计思想,我们在React-Native项目根目录定义一个GradientColorView.js的文件,代码如下:
分析以上代码,主要是由5部分组成。
1、注解部分。@providesModule注解表示当前JS组件是需要与原生组件相互映射的,其值RCTGradientColorView与前面第3步中GradientColorViewManager类中的getName()值保持一致性,这样才能完成映射关系。这里不得不提一点,ViewManager这个类设计得并不是特别合理,如果getName()的值也通过Java类注解来完成,保持和JS层的呼应关系,将更容易让人理解。
2、初始化对象。PropTypes、React、View、requireNativeComponent等对象在后面会使用到,所以需要先实例化。这一点是ReactJS的语法,有兴趣自行研究。
3、定义组件属性。最基本的View.propTypes属性,还有两个自定义的的startColor、endColor。这样使用组件的地方就可以使用如startColor=‘red’进行开发了。
4、组件渲染。这一步使用了JSX(JavaScript XML)语法,自定义了NativeGradientColorView标签,实际上是对GradientColorView做了一层包装。
5、组件导出。最后一行代码 module.exports = GradientColorView 声明了GradientColorView标签可以在其他JS文件中调用。
如何使用一共分两步:
1,导入声明
2,作为标签使用
使用效果如下:
这里简要梳理一下步骤:
1、自定义View开发
2、编写相应ViewManager,实例化View,定义映射Name,注解API属性方法
3、Activity中注册ViewManager
4、编写Javascript组件,添加注解映射,定义标签对象、属性,提供给外部。
5、import组件,使用。
从以上步骤,大致可以了解React-Native组件的工作流程:
JSX标签解析 ——Javascript组件调用——Bridge——ViewManager反射——创建并配置View
本博客不定期持续更新,欢迎关注和交流:
http://blog.csdn.net/megatronkings
在Android原生Java端的组件分为两种类型:视图组件(View)和功能组件(Module),React-Native官方为开发者提供了大量的常用组件,位于com.facebook.react.views包和com.facebook.react.modules包下面,基本覆盖了所有类型的组件,包括文本,输入框,图片等。
本文GradientColorView(颜色渐变视图)为例,演示如何自定义一个原生View组件,并在JS中调用。
1、Java层自定义GradientColorView
package com.myproject; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.GradientDrawable.Orientation; import android.view.View; public class GradientColorView extends View { private GradientDrawable mDrawable; private int mStartColor; private int mEndColor; public GradientColorView(Context context) { super(context); mDrawable = new GradientDrawable(); mDrawable.setOrientation(Orientation.LEFT_RIGHT); } public void setStartColor(int startColor) { this.mStartColor = startColor; } public void setEndColor(int endColor) { this.mEndColor = endColor; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mDrawable.setBounds(0, 0, getWidth(), getHeight()); mDrawable.setColors(new int[]{mStartColor, mEndColor}); mDrawable.draw(canvas); } }
代码非常简单,自定义一个普通View,并提供两个控制渐变颜色的方法setStartColor和setEndColor,然后再onDraw方法里面绘制在画布上。
2、Java层自定义ViewManager
编写UI管理器,如果没有特殊要求,直接继承SimpleViewManager,并使用上一步的GradientColorView作为泛型类型。这里需要实现两个简单的方法getName和createViewInstance,前者用来映射JS中的组件(后面讲到),后者用来创建View实例。
同时需要提供两个被注入的方法setStartColor和setEndColor,必须使用ReactProp注解,name值与JS中属性名保持一致。
package com.myproject; import javax.annotation.Nullable; import com.facebook.react.uimanager.SimpleViewManager; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.annotations.ReactProp; public class GradientColorViewManager extends SimpleViewManager<GradientColorView> { // React-Native官方大多数自定义View都是用RCT开头,这里保持规范性 private static final String REACT_CLASS = "RCTGradientColorView"; @Override public String getName() { // 此处name在后面JS组件开发时会用到,需要统一命名 return REACT_CLASS; } @Override protected GradientColorView createViewInstance(ThemedReactContext reactContext) { // GradientColorView的实例化 return new GradientColorView(reactContext); } /** * ReactProp注解方法,React-Native底层会自动反射调用, * name字符串值与JS中配置的属性名保持一致 * customType字符串值表示颜色转换,不配置会转换异常 * * @param view GradientColorView实例 * @param startColor 渐变起始值 */ @ReactProp(name = "startColor", customType = "Color") public void setStartColor(GradientColorView view, @Nullable Integer startColor) { view.setStartColor(startColor); } /** * ReactProp注解方法,React-Native底层会自动反射调用, * name字符串值与JS中配置的属性名保持一致 * customType字符串值表示颜色转换,不配置会转换异常 * * @param view GradientColorView实例 * @param endColor 渐变结束值 */ @ReactProp(name = "endColor", customType = "Color") public void setEndColor(GradientColorView view, @Nullable Integer endColor) { view.setEndColor(endColor); } }
3、Java层注册ViewManager
上一步中编写的GradientColorViewManager需要手动注册,否则React-Native底层无法映射识别,具体注册是在Activity中,代码如下:/** * A list of packages used by the app. If the app uses additional views * or modules besides the default ones, add more packages here. */ @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new ReactPackage() { @Override public List<ViewManager> createViewManagers( ReactApplicationContext reactContext) { return Arrays.<ViewManager>asList(new GradientColorViewManager()); } @Override public List<NativeModule> createNativeModules( ReactApplicationContext reactContext) { return Collections.emptyList(); } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } } ); }
除了必要的MainReactPackage之外,注册了一个匿名内部类ReactPackage,包含了GradientColorViewManager。这样GradientColorViewManager的注册就完成了。
接下来需要开发JS层对应的组件了。
4、JS层开发GradientColorView组件
前三步中,Android原生组件开发完成了,但是如果要在设备中显示出来,还需要通过由Javascript层进行组件映射,如何映射是由Bridge(连接Java和Javascript的JNI库)完成的,这里不细讲。我们接下来编写桥梁另一端的代码。前面说过,Javascript层也遵循了组件化设计思想,我们在React-Native项目根目录定义一个GradientColorView.js的文件,代码如下:
/** * @providesModule RCTGradientColorView */ 'use strict'; var PropTypes = require('ReactPropTypes'); var React = require('React'); var View = require('View'); var requireNativeComponent = require('requireNativeComponent'); var GradientColorView = React.createClass({ // 定义两个控制颜色的属性,与Java层GradientColorView中@ReactProp注解的方法参数保持一致 propTypes: { ...View.propTypes, startColor: PropTypes.string, endColor: PropTypes.string, }, render: function() { return ( <NativeGradientColorView style={this.props.style} startColor={this.props.startColor} endColor={this.props.endColor}/> );} }); var NativeGradientColorView = requireNativeComponent('RCTGradientColorView', GradientColorView); module.exports = GradientColorView;
分析以上代码,主要是由5部分组成。
1、注解部分。@providesModule注解表示当前JS组件是需要与原生组件相互映射的,其值RCTGradientColorView与前面第3步中GradientColorViewManager类中的getName()值保持一致性,这样才能完成映射关系。这里不得不提一点,ViewManager这个类设计得并不是特别合理,如果getName()的值也通过Java类注解来完成,保持和JS层的呼应关系,将更容易让人理解。
2、初始化对象。PropTypes、React、View、requireNativeComponent等对象在后面会使用到,所以需要先实例化。这一点是ReactJS的语法,有兴趣自行研究。
3、定义组件属性。最基本的View.propTypes属性,还有两个自定义的的startColor、endColor。这样使用组件的地方就可以使用如startColor=‘red’进行开发了。
4、组件渲染。这一步使用了JSX(JavaScript XML)语法,自定义了NativeGradientColorView标签,实际上是对GradientColorView做了一层包装。
5、组件导出。最后一行代码 module.exports = GradientColorView 声明了GradientColorView标签可以在其他JS文件中调用。
5、GradientColorView组件的使用
到这里,自定义组件GradientColorView已经开发完成了,接下来提供给开发者进行使用。如何使用一共分两步:
1,导入声明
import GradientColorView from './GradientColorView.js';
2,作为标签使用
<GradientColorView style={{width:80,height:80}} startColor="yellow" endColor="red"/>
使用效果如下:
6、总结
开发React-Native组件,涉及到Java(或Objective-C)和Javascript至少两种编程语言,流程比较繁琐,技术栈要求较高,除非迫不得已,一般不会这么做。这里简要梳理一下步骤:
1、自定义View开发
2、编写相应ViewManager,实例化View,定义映射Name,注解API属性方法
3、Activity中注册ViewManager
4、编写Javascript组件,添加注解映射,定义标签对象、属性,提供给外部。
5、import组件,使用。
从以上步骤,大致可以了解React-Native组件的工作流程:
JSX标签解析 ——Javascript组件调用——Bridge——ViewManager反射——创建并配置View
本博客不定期持续更新,欢迎关注和交流:
http://blog.csdn.net/megatronkings
相关文章推荐
- sgu 194 Reactor Cooling(有容量上下界的无源无汇可行流)
- ReactJS[未完待续]
- React.js深入学习详细解析
- React Native学习之RCTDeviceEventEmitter(类似iOS的NSNotificationCenter)简单用法以及背景透明
- ReactNative更换JSContext增加注入方法
- React-Native Android 学习笔记——2,自定义 logger
- window 64bit 下react navtive安装
- React-native学习笔记之<BackAndroid>
- 对于ApiCloud和React Native的选择
- twisted转载二即异步编程初探与reactor模式
- React-Native(二)引入项目,在windows上运行已有的Demo for Android
- react-native 之布局篇
- 通过React Native动态更新iOS应用
- React-native Android 环境配置
- React-开发工具
- 困惑:关于angular backbone react
- ReactNative列表ListView
- 移动互联之-- React Native
- React.js深入学习详细解析
- << React Native 入门与实战>>----第1章 React Native简介