直接寫一個Demo例子,有相關功底的確定明白,會對特別的地方進行提醒,本文基於https://blog.csdn.net/lintcgirl/article/details/53489490,可是按此連接文章不可用。java
首先是JAVA部分:react
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沒法解決這個方案,若有能解決的朋友請告訴我。android
下面是自定義的viewios
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 }
第二坑:註釋部分的方法在新版本已經去除了shell
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部分:canvas
circle.jsreact-native
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的第一個參數須要一致,不少教程這裏不一致,致使找不到這個原生viewapp
App.jside
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 <MCircle 23 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必須名字也一致,這不用多說了測試