我创建了一个CustomView SignatureView.java,它扩展了LinearLayout以便在Android Native中捕获签名。
并创建了SignatureCapturePackage.java和SignatureCaptureViewManager.java
public class SignatureCaptureMainView extends LinearLayout { .... public void saveImage(){ //Save image to file } }
这个Package类
public class SignatureCapturePackage implements ReactPackage { private Activity mCurrentActivity; public RSSignatureCapturePackage(Activity activity) { mCurrentActivity = activity; } @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Arrays.<NativeModule>asList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactApplicationContext) { return Arrays.<ViewManager>asList(new SignatureCaptureViewManager(mCurrentActivity)); } @Override public List<Class<? extends JavaScriptModule>> createJSModules() { return Arrays.asList(); } }
这是ViewManager类
public class SignatureCaptureViewManager extends ViewGroupManager<SignatureCaptureMainView> { private Activity mCurrentActivity; public static final String PROPS_SAVE_IMAGE_FILE="saveImageFileInExtStorage"; public static final String PROPS_VIEW_MODE = "viewMode"; public RSSignatureCaptureViewManager(Activity activity) { mCurrentActivity = activity; } @Override public String getName() { return "SignatureView"; } @ReactProp(name = PROPS_SAVE_IMAGE_FILE) public void setSaveImageFileInExtStorage(SignatureCaptureMainView view, @Nullable Boolean saveFile) { Log.d("React View manager setSaveFileInExtStorage:", "" + saveFile); if(view!=null){ view.setSaveFileInExtStorage(saveFile); } } @ReactProp(name = PROPS_VIEW_MODE) public void setViewMode(SignatureCaptureMainView view, @Nullable String viewMode) { Log.d("React View manager setViewMode:", "" + viewMode); if(view!=null){ view.setViewMode(viewMode); } } @Override public SignatureCaptureMainView createViewInstance(ThemedReactContext context) { Log.d("React"," View manager createViewInstance:"); return new SignatureCaptureMainView(context, mCurrentActivity); } }
这是Signature.js捆绑包
var React = require('react-native'); var { PropTypes, requireNativeComponent, View, } = React; class SignatureCapture extends React.Component { constructor() { super(); this.onChange = this.onChange.bind(this); } onChange(event) { console.log("Signature ON Change Event"); if (!this.props.onSaveEvent) { return; } this.props.onSaveEvent({ pathName: event.nativeEvent.pathName, encoded: event.nativeEvent.encoded, }); } render() { return ( <SignatureView {...this.props} style={{flex: 1}} onChange={this.onChange} /> ); } save(){ } } SignatureCapture.propTypes = { ...View.propTypes, saveImageFileInExtStorage: PropTypes.bool, viewMode:PropTypes.string }; var SignatureView = requireNativeComponent('SignatureView', SignatureCapture, { nativeOnly: {onChange: true} }); module.exports = SignatureCapture;
我正在像这样在ReactNative中使用模块
<SignatureCapture onSaveEvent={this._onSaveEvent} saveImageFileInExtStorage={false} viewMode={"portrait"}/>
一切正常。但是我仅在反应侧发生某些单击事件时才必须保存图像。即,我必须从反应式js代码调用SignatureCaptureMainView的saveImage()方法。
我该如何实现?请帮助
按照@agent_hunt给定的指针。
检查此博客进行解释
我在SignatureCaptureViewManager中使用了ui管理器命令。发布我的解决方案
public class SignatureCaptureViewManager extends ViewGroupManager<SignatureCaptureMainView> { private Activity mCurrentActivity; public static final String PROPS_SAVE_IMAGE_FILE="saveImageFileInExtStorage"; public static final String PROPS_VIEW_MODE = "viewMode"; public static final int COMMAND_SAVE_IMAGE = 1; public SignatureCaptureViewManager(Activity activity) { mCurrentActivity = activity; } @Override public String getName() { return "SignatureView"; } @ReactProp(name = PROPS_SAVE_IMAGE_FILE) public void setSaveImageFileInExtStorage(SignatureCaptureMainView view, @Nullable Boolean saveFile) { Log.d("React View manager setSaveFileInExtStorage:", "" + saveFile); if(view!=null){ view.setSaveFileInExtStorage(saveFile); } } @ReactProp(name = PROPS_VIEW_MODE) public void setViewMode(SignatureCaptureMainView view, @Nullable String viewMode) { Log.d("React View manager setViewMode:", "" + viewMode); if(view!=null){ view.setViewMode(viewMode); } } @Override public SignatureCaptureMainView createViewInstance(ThemedReactContext context) { Log.d("React"," View manager createViewInstance:"); return new SignatureCaptureMainView(context, mCurrentActivity); } @Override public Map<String,Integer> getCommandsMap() { Log.d("React"," View manager getCommandsMap:"); return MapBuilder.of( "saveImage", COMMAND_SAVE_IMAGE); } @Override public void receiveCommand( SignatureCaptureMainView view, int commandType, @Nullable ReadableArray args) { Assertions.assertNotNull(view); Assertions.assertNotNull(args); switch (commandType) { case COMMAND_SAVE_IMAGE: { view.saveImage(); return; } default: throw new IllegalArgumentException(String.format( "Unsupported command %d received by %s.", commandType, getClass().getSimpleName())); } } }
为了向ViewManager发送命令,我在Signature Capture组件中添加了此方法
class SignatureCapture extends React.Component { constructor() { super(); this.onChange = this.onChange.bind(this); } onChange(event) { console.log("Signature ON Change Event"); if (!this.props.onSaveEvent) { return; } this.props.onSaveEvent({ pathName: event.nativeEvent.pathName, encoded: event.nativeEvent.encoded, }); } render() { return ( <SignatureView {...this.props} style={{flex: 1}} onChange= {this.onChange} /> ); } saveImage(){ UIManager.dispatchViewManagerCommand( React.findNodeHandle(this), UIManager.SignatureView.Commands.saveImage, [], ); } } SignatureCapture.propTypes = { ...View.propTypes, rotateClockwise: PropTypes.bool, square:PropTypes.bool, saveImageFileInExtStorage: PropTypes.bool, viewMode:PropTypes.string }; var SignatureView = requireNativeComponent('SignatureView', SignatureCapture, { nativeOnly: {onChange: true} }); module.exports = SignatureCapture;
这就是我在父级Signature组件中使用SignatureCapture组件的方式
class Signature extends Component { render() { return ( <View style={{ flex: 1, flexDirection: "column" }}> <SignatureCapture style={{ flex: 8 }} ref="sign", onSaveEvent={this._onSaveEvent} saveImageFileInExtStorage={false} viewMode={"portrait"}/> <TouchableHighlight style={{ flex: 2 }} onPress={() => { this.saveSign() } } > <Text>Save</Text> </TouchableHighlight> </View> ); } // Calls Save method of native view and triggers onSaveEvent callback saveSign() { this.refs["sign"].saveImage(); } _onSaveEvent(result) { //result.encoded - for the base64 encoded png //result.pathName - for the file path name console.log(result); } } export default Signature;