致敬 facebook 。reactnative 是factbook推出的移动端跨平台框架,给跨平台开发带来了新的实现。
它封装了大量常用的基础控件,但是在开发的过程中并不能满足个性的开发。有幸的是 rn团队为开发者接入自定义控件提供了解决方案。本章主要记录Android平台上如何使用自定义控件。
1.Android端原生实现
1.1 继承ViewManager进行自定义控件开发
1 2 3 4 5 6 7 8 9 10 11 12
| public class GameViewManager extends SimpleViewManager<ImageView> { @Override public String getName() { return "rnimageview"; }
@Override protected ImageView createViewInstance(ThemedReactContext reactContext) { return new ImageView(): } }
|
getName 方法返回的值 就是我们在 rn的javascript文件里面使用的view标签名字
通过createViewInstance方法返回要使用控件的实例
1.2 支持自定义属性和方法
我们需要添加一些动态的值通过属性的方式让我们的原生控件接收,rn提供了一套通信方式,我们在ViewManager的实现类中添加如下方法:
1 2 3 4 5 6 7
| @ReactMethod @ReactProp(name = "gameURL") public void setUrl(JdGameSurface view, @Nullable String sources) { Toast.makeText(view.getContext(),"seturl",Toast.LENGTH_SHORT).show(); view.loadJsFromAssets("fish-android.js"); view.start(); }
|
添加 ReactMethod 注解的方法可以在javascript文件中访问, 这样我们可以在javascript中动态设值。
@ReactProp(name = “gameURL”) 此注解标识我们为本view添加了一个gameURL的属性 。 通过这样我们就完成了对应属性的添加
1.3 注册我们的自定义控件
首先我们 新建ReactPackage的实现类,然后将我们的自定义ViewManager 在createViewManagers方法中添加到集合返回,如下代码所示 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class GameReactPackage implements ReactPackage {
@Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Collections.emptyList(); }
@Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { ArrayList<ViewManager> viewManagers = new ArrayList<>(); viewManagers.add(new GameViewManager()); return viewManagers; } }
|
其次,在application中将我们新建的ReactPackage类,添加到rn中注册
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
| public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; }
@Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new GameReactPackage()//重要 ); }
@Override protected String getJSMainModuleName() { return "index"; } };
@Override public ReactNativeHost getReactNativeHost() { return mReactNativeHost; }
@Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); } }
|
主要是在 getPackages 方法中将此 ReactPackage 添加到集合中返回 。
到此为止,我么就将Android中原生开发进行完毕,下面开始讲解怎么在 javascript文件中使用此自定义控件
2. 在RN中使用自定义控件
为方便使用,我们实现一个 rn模块对view进行统一的管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { requireNativeComponent } from 'react-native';
class JDGameView extends React.Component{ render() { return <RNJDGame {...this.props} />; } }
JDGameView.propTypes = { gameURL:PropTypes.string, ...View.propTypes };
var RNJDGame = requireNativeComponent('RNJDGame',JDGameView);
export default JDGameView;
|
在我们需要使用此view的地方进行引入即可
1 2 3 4 5
| render() { return ( <JDGameView gameURL="xxxxxxx"></JDGameView> ); }
|
至此,我们通过代码和讲解,实现了rn中进行自定义控件的完整流程。