zoukankan      html  css  js  c++  java
  • ReactNative如何在JS中引用原生自定义控件(rn变化太快,网上很多教程有坑,这个我研究后可用,特意分享)

    直接写一个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     @Override
    10     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     @Override
    17     public boolean getUseDeveloperSupport() {
    18       return BuildConfig.DEBUG;
    19     }
    20 
    21     @Override
    22     protected List<ReactPackage> getPackages() {
    23       return Arrays.<ReactPackage>asList(
    24           new MainReactPackage(),
    25               new AppReactPackage()
    26       );
    27     }
    28 
    29     @Override
    30     protected String getJSMainModuleName() {
    31       return "index";
    32     }
    33   };
    34 
    35   @Override
    36   public ReactNativeHost getReactNativeHost() {
    37     return mReactNativeHost;
    38   }
    39 
    40   @Override
    41   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     @Override
    16     public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    17         return Collections.emptyList();
    18     }
    19 
    20 //    @Override
    21 //    public List<Class<? extends JavaScriptModule>> createJSModules() {
    22 //        return Collections.emptyList();
    23 //    }
    24 
    25     @Override
    26     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 radius
    23      */
    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     @Override
    34     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     @Override
    15     public String getName() {
    16         return "MCircle";
    17     }
    18 
    19     /**
    20      * 创建UI组件实例
    21      */
    22     @Override
    23     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.propTypes
    21   },
    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,
    ' +
    13     'Cmd+D or shake for dev menu',
    14   android: 'Double tap R on your keyboard to reload,
    ' +
    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                     <MCircle
    23                           style={{ 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必须名字也一致,这不用多说了

  • 相关阅读:
    【经验总结】- IDEA无法显示Project目录怎么办
    JSON API免费接口(转)
    电子商务(电销)平台中订单模块(Order)数据库设计明细(转)
    typora 快捷键
    table 随td固宽
    跨域请求
    在网址前加神秘字母,让你打开新世界(z)
    vux安装中遇到的坑(转)
    常用正则表达示
    mui 浏览器一样自动缩放
  • 原文地址:https://www.cnblogs.com/lee0oo0/p/9157021.html
Copyright © 2011-2022 走看看