Invoke toDataURL on Android in a more proper way

This commit is contained in:
Horcrux
2017-01-22 18:27:35 +08:00
parent 8cd78e830e
commit 3765e52c67
6 changed files with 48 additions and 75 deletions
@@ -2,6 +2,8 @@ package com.horcrux.svg;
import android.util.SparseArray;
import javax.annotation.Nullable;
public class SvgInstancesManager {
private static final SparseArray<SvgViewShadowNode> mTagToShadowNode = new SparseArray<>();
private static final SparseArray<SvgView> mTagToSvgView = new SparseArray<>();
@@ -19,11 +21,11 @@ public class SvgInstancesManager {
mTagToSvgView.remove(tag);
}
static SvgView getSvgViewByTag(int tag) {
static @Nullable SvgView getSvgViewByTag(int tag) {
return mTagToSvgView.get(tag);
}
static SvgViewShadowNode getShadowNodeByTag(int tag) {
static @Nullable SvgViewShadowNode getShadowNodeByTag(int tag) {
return mTagToShadowNode.get(tag);
}
}
@@ -51,6 +51,6 @@ public class SvgPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Collections.emptyList();
return Collections.<NativeModule>singletonList(new SvgViewModule(reactContext));
}
}
@@ -13,17 +13,12 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.util.Log;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.TextureView;
import android.view.View;
import com.facebook.react.ReactRootView;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.facebook.react.uimanager.events.TouchEvent;
import com.facebook.react.uimanager.events.TouchEventCoalescingKeyHelper;
@@ -188,10 +183,8 @@ public class SvgView extends View {
dispatch(ev, TouchEventType.CANCEL);
}
public void onDataURL() {
WritableMap event = Arguments.createMap();
event.putString("base64", getShadowNode().getBase64());
mEventEmitter.receiveEvent(getId(), Events.EVENT_DATA_URL.toString(), event);
public String toDataURL() {
return getShadowNode().getBase64();
}
@@ -14,16 +14,9 @@ import android.graphics.Bitmap;
import com.facebook.yoga.YogaMeasureMode;
import com.facebook.yoga.YogaMeasureFunction;
import com.facebook.yoga.YogaNodeAPI;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
/**
* ViewManager for RNSVGSvgView React views. Renders as a {@link SvgView} and handles
* invalidating the native view on shadow view updates happening in the underlying tree.
@@ -31,7 +24,6 @@ import javax.annotation.Nullable;
public class SvgViewManager extends BaseViewManager<SvgView, SvgViewShadowNode> {
private static final String REACT_CLASS = "RNSVGSvgView";
private static final int COMMAND_TO_DATA_URL = 100;
private static final YogaMeasureFunction MEASURE_FUNCTION = new YogaMeasureFunction() {
@Override
public long measure(
@@ -76,36 +68,4 @@ public class SvgViewManager extends BaseViewManager<SvgView, SvgViewShadowNode>
root.setBitmap((Bitmap) extraData);
}
@Override
public @Nullable Map<String, Integer> getCommandsMap() {
Map<String, Integer> commandsMap = super.getCommandsMap();
if (commandsMap == null) {
commandsMap = new HashMap<>();
}
commandsMap.put("toDataURL", COMMAND_TO_DATA_URL);
return commandsMap;
}
@Override
@Nullable
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
MapBuilder.Builder<String, Object> builder = MapBuilder.builder();
for (SvgView.Events event : SvgView.Events.values()) {
builder.put(event.toString(), MapBuilder.of("registrationName", event.toString()));
}
return builder.build();
}
@Override
public void receiveCommand(SvgView root, int commandId, @Nullable ReadableArray args) {
super.receiveCommand(root, commandId, args);
switch (commandId) {
case COMMAND_TO_DATA_URL:
root.onDataURL();
break;
}
}
}
@@ -0,0 +1,38 @@
/**
* Copyright (c) 2015-present, Horcrux.
* All rights reserved.
*
* This source code is licensed under the MIT-style license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.horcrux.svg;
import android.util.Log;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
public class SvgViewModule extends ReactContextBaseJavaModule {
public SvgViewModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "RNSVGSvgViewManager";
}
@ReactMethod
public void toDataURL(int tag, Callback successCallback) {
SvgView svg = SvgInstancesManager.getSvgViewByTag(tag);
if (svg != null) {
successCallback.invoke(svg.toDataURL());
}
}
}
+3 -23
View File
@@ -8,12 +8,10 @@ import {
StyleSheet,
UIManager,
findNodeHandle,
NativeModules,
Platform
NativeModules
} from 'react-native';
import extractViewBox from '../lib/extract/extractViewBox';
import {ViewBoxAttributes} from '../lib/attributes';
import _ from 'lodash';
const RNSVGSvgViewManager = NativeModules.RNSVGSvgViewManager;
@@ -64,24 +62,8 @@ class Svg extends Component{
this.root.setNativeProps(...args);
};
toDataURL = Platform.OS === 'ios' ? (callback = _.noop) => {
RNSVGSvgViewManager.toDataURL(findNodeHandle(this.root), callback);
} : (callback = _.noop) => {
let node = findNodeHandle(this.root);
this.onDataURLCallbacks.push(callback);
UIManager.dispatchViewManagerCommand(
node,
UIManager.RNSVGSvgView.Commands.toDataURL,
null
);
};
_onDataURL = (e) => {
while (this.onDataURLCallbacks.length) {
let callback = this.onDataURLCallbacks.shift();
callback(e.nativeEvent.base64);
}
toDataURL = (callback: Function) => {
callback && RNSVGSvgViewManager.toDataURL(findNodeHandle(this.root), callback);
};
render() {
@@ -108,7 +90,6 @@ class Svg extends Component{
},
dimensions
]}
onDataURL={this._onDataURL}
/>;
}
}
@@ -119,5 +100,4 @@ const NativeSvgView = requireNativeComponent('RNSVGSvgView', null, {
}
});
export default Svg;