直接写一个Demo例子,有相关功底的肯定明白,会对特别的地方进行提醒,本文基于https://blog.csdn.net/lintcgirl/article/details/53489490,但是按此链接文章不可用。
首先是JAVA部分:
1 import com.facebook.react.ReactActivity; 2 ?3 public class MainActivity extends ReactActivity { 4 ?5 ????/** 6 ?????* Returns the name of the main component registered from JavaScript. 7 ?????* This is used to schedule rendering of the component. 8 ?????*/ 9 ????@Override10 ????protected String getMainComponentName() {11 ????????return "RNMyTest";12 ????}13 }
1 import android.app.Application; 2 ?3 import com.facebook.react.ReactApplication; 4 import com.facebook.react.ReactNativeHost; 5 import com.facebook.react.ReactPackage; 6 import com.facebook.react.shell.MainReactPackage; 7 import com.facebook.soloader.SoLoader; 8 import com.rnmytest.view.AppReactPackage; 9 10 import java.util.Arrays;11 import java.util.List;12 13 public class MainApplication extends Application implements ReactApplication {14 15 ??private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {16 ????@Override17 ????public boolean getUseDeveloperSupport() {18 ??????return BuildConfig.DEBUG;19 ????}20 21 ????@Override22 ????protected List<ReactPackage> getPackages() {23 ??????return Arrays.<ReactPackage>asList(24 ??????????new MainReactPackage(),25 ??????????????new AppReactPackage()26 ??????);27 ????}28 29 ????@Override30 ????protected String getJSMainModuleName() {31 ??????return "index";32 ????}33 ??};34 35 ??@Override36 ??public ReactNativeHost getReactNativeHost() {37 ????return mReactNativeHost;38 ??}39 40 ??@Override41 ??public void onCreate() {42 ????super.onCreate();43 ????SoLoader.init(this, /* native exopackage */ false);44 ??}45 }
第一坑,之前的项目可能创建时间太久,ReactApplication完全无法引用,后面我是重新新建一个demo测试后能成功导入,各种百度google无法解决这个方案,如有能解决的朋友请告诉我。
下面是自定义的view
1 import com.facebook.react.ReactPackage; 2 import com.facebook.react.bridge.NativeModule; 3 import com.facebook.react.bridge.ReactApplicationContext; 4 import com.facebook.react.uimanager.ViewManager; 5 import java.util.Arrays; 6 import java.util.Collections; 7 import java.util.List; 8 ?9 /**10 ?* Created by bingmingli on 2018/6/8.11 ?*/12 13 public class AppReactPackage implements ReactPackage {14 15 ????@Override16 ????public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {17 ????????return Collections.emptyList();18 ????}19 20 // ???@Override21 // ???public List<Class<? extends JavaScriptModule>> createJSModules() {22 // ???????return Collections.emptyList();23 // ???}24 25 ????@Override26 ????public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {27 ????????return Arrays.<ViewManager>asList(28 ????????????????new CircleManager()29 ????????);30 ????}31 }
第二坑:注释部分的方法在新版本已经去除了
1 import android.content.Context; 2 import android.graphics.Canvas; 3 import android.graphics.Paint; 4 import android.util.Log; 5 import android.view.View; 6 ?7 import com.facebook.react.uimanager.PixelUtil; 8 ?9 public class CircleView extends View {10 ????private final String TAG = "CircleView";11 ????private Paint mPaint; // 画笔12 ????private float mRadius; ?// 圆的半径13 14 ????public CircleView(Context context) {15 ????????super(context);16 ????????mPaint = new Paint();17 ????????mPaint.setColor(0xAA000000);18 ????}19 20 ????/**21 ?????* 设置圆的半径22 ?????* @param radius23 ?????*/24 ????public void setRadius(Integer radius) {25 ????????/**26 ?????????* 由于JS传过的数字是dip单位,需要转换为实际像素27 ?????????* 使用com.facebook.react.uimanager包中的PixelUtil,进行转换28 ?????????*/29 ????????mRadius = PixelUtil.toPixelFromDIP(radius);30 ????????invalidate();31 ????}32 33 ????@Override34 ????protected void onDraw(Canvas canvas) {35 ????????super.onDraw(canvas);36 ????????canvas.drawCircle(mRadius, mRadius, mRadius, mPaint); // 画一个半径为100px的圆37 ????????Log.d(TAG, "绘图");38 ????}39 }
1 import com.facebook.react.uimanager.SimpleViewManager; 2 import com.facebook.react.uimanager.ThemedReactContext; 3 import com.facebook.react.uimanager.annotations.ReactProp; 4 ?5 /** 6 ?* Created by bingmingli on 2018/6/8. 7 ?*/ 8 ?9 public class CircleManager extends SimpleViewManager<CircleView> {10 11 ????/**12 ?????* 设置js引用名13 ?????*/14 ????@Override15 ????public String getName() {16 ????????return "MCircle";17 ????}18 19 ????/**20 ?????* 创建UI组件实例21 ?????*/22 ????@Override23 ????protected CircleView createViewInstance(ThemedReactContext reactContext) {24 ????????return new CircleView(reactContext);25 ????}26 27 ????/**28 ?????* 传输半径参数29 ?????*/30 ????@ReactProp(name = "radius")31 ????public void setRadius(CircleView view, Integer radius) {32 ????????view.setRadius(radius);33 ????}34 }
下面是JS部分:
circle.js
1 import React, { Component } from ‘react‘; 2 import { 3 ??View, 4 ??requireNativeComponent 5 } from ‘react-native‘; 6 ?7 import PropTypes from ‘prop-types‘ 8 // const RCTCircle = requireNativeComponent(‘MCircle‘, { 9 // ??propTypes: {10 // ????radius: PropTypes.number,11 // ????...View.propTypes // 包含默认的View的属性12 // ??},13 // });14 // module.exports=RCTCircle;15 16 var iface = {17 ??name: ‘MCircle‘,18 ??propTypes: {19 ????radius: PropTypes.number,20 ????...View.propTypes21 ??},22 };23 ?24 module.exports = requireNativeComponent(‘MCircle‘, iface);
第三坑:PropTypes的导入方式为import PropTypes from ‘prop-types‘
第四坑:...View.propTypes这个必须有,不然自己的属性不能识别
第五坑:iface里面的name 与 requireNativeComponent的第一个参数需要一致,很多教程这里不一致,导致找不到这个原生view
App.js
1 import React, { Component } from ‘react‘; 2 import { 3 ??Platform, 4 ??StyleSheet, 5 ??Text, 6 ??View 7 } from ‘react-native‘; 8 ?9 import MCircle from ‘./circle‘;10 11 const instructions = Platform.select({12 ??ios: ‘Press Cmd+R to reload,\n‘ +13 ????‘Cmd+D or shake for dev menu‘,14 ??android: ‘Double tap R on your keyboard to reload,\n‘ +15 ????‘Shake or press menu button for dev menu‘,16 });17 18 export default class App extends Component<Props> {19 ??render() {20 ????return (21 ????????????????<View>22 ????????????????????<MCircle23 ??????????????????????????style={{width: 100, height: 100}}24 ??????????????????????????radius={50}25 ????????????????????/>26 ????????????????</View>27 ????????????); 28 ??}29 }30 31 const styles = StyleSheet.create({32 ??container: {33 ????flex: 1,34 ????justifyContent: ‘center‘,35 ????alignItems: ‘center‘,36 ????backgroundColor: ‘#F5FCFF‘,37 ??},38 ??welcome: {39 ????fontSize: 20,40 ????textAlign: ‘center‘,41 ????margin: 10,42 ??},43 ??instructions: {44 ????textAlign: ‘center‘,45 ????color: ‘#333333‘,46 ????marginBottom: 5,47 ??},48 });
提醒:导入的view必须名字也一致,这不用多说了
ReactNative如何在JS中引用原生自定义控件(rn变化太快,网上很多教程有坑,这个我研究后可用,特意分享)
原文地址:https://www.cnblogs.com/lee0oo0/p/9157021.html