React-Native系列——自定义View组件开发
2017-09-15 14:49
621 查看
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中调用。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
代码非常简单,自定义一个普通View,并提供两个控制渐变颜色的方法setStartColor和setEndColor,然后再onDraw方法里面绘制在画布上。
编写UI管理器,如果没有特殊要求,直接继承SimpleViewManager,并使用上一步的GradientColorView作为泛型类型。
这里需要实现两个简单的方法getName和createViewInstance,前者用来映射JS中的组件(后面讲到),后者用来创建View实例。
同时需要提供两个被注入的方法setStartColor和setEndColor,必须使用ReactProp注解,name值与JS中属性名保持一致。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
上一步中编写的GradientColorViewManager需要手动注册,否则React-Native底层无法映射识别,具体注册是在Activity中,代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
除了必要的MainReactPackage之外,注册了一个匿名内部类ReactPackage,包含了GradientColorViewManager。这样GradientColorViewManager的注册就完成了。
接下来需要开发JS层对应的组件了。
前三步中,Android原生组件开发完成了,但是如果要在设备中显示出来,还需要通过由Javascript层进行组件映射,如何映射是由Bridge(连接Java和Javascript的JNI库)完成的,这里不细讲。我们接下来编写桥梁另一端的代码。
前面说过,Javascript层也遵循了组件化设计思想,我们在React-Native项目根目录定义一个GradientColorView.js的文件,代码如下:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
分析以上代码,主要是由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文件中调用。
到这里,自定义组件GradientColorView已经开发完成了,接下来提供给开发者进行使用。
如何使用一共分两步:
1,导入声明
2,作为标签使用
使用效果如下:
开发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
在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); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
代码非常简单,自定义一个普通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); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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(); } } ); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
除了必要的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;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
分析以上代码,主要是由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';1
2,作为标签使用
<GradientColorView style={{width:80,height:80}} startColor="yellow" endColor="red"/>1
使用效果如下:
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
相关文章推荐
- React-Native系列Android——自定义View组件开发
- 【React Native开发】React Native控件之WebView组件详解以及实例使用(22)
- 【React Native开发】 - WebView组件的使用
- 【React Native开发】 - ViewParger轮播组件
- React Native 开发之 (07) 常用组件-View
- 【React Native开发】React Native控件之Touchable*系列组件详解(18)
- 【React Native开发】React Native控件之Touchable*系列组件详解(18)
- React Native系列——WebView组件使用介绍
- 【Android 应用开发】 自定义组件 宽高适配方法, 手势监听器操作组件, 回调接口维护策略, 绘制方法分析 -- 基于 WheelView 组件分析自定义组件
- Android官方开发文档Training系列课程中文版:创建自定义View之View的创建
- Android开发中自定义View设定到FrameLayout布局中实现多组件显示
- Android官方开发文档Training系列课程中文版:创建自定义View之View的绘制
- React Native按钮详解|Touchable系列组件使用详解
- React Native自定义View解析Emoji
- (八)React Native---WebView组件
- 《React-Native系列》13、 组件封装之Dialog(iOS和Android通用)
- react-native 自定义view向js暴露接口方法
- React Native开发之——组件TextInput(2)
- iOS开发系列之常用自定义控件开发集—自定义对话框(UIAlertView)控件开发
- iOS开发系列 ---- UI (自定义TableView)