mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-12 02:19:45 +00:00
Fix Touch events on Android
Fix Touch events on Android, using region.contains point instead of Bitmap
This commit is contained in:
@@ -76,13 +76,17 @@ public class GroupShadowNode extends RenderableShadowNode {
|
|||||||
return hitSelf;
|
return hitSelf;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix combinedMatrix = new Matrix();
|
Matrix groupMatrix = new Matrix(mMatrix);
|
||||||
|
|
||||||
if (matrix != null) {
|
if (matrix != null) {
|
||||||
combinedMatrix.postConcat(matrix);
|
groupMatrix.postConcat(matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
combinedMatrix.postConcat(mMatrix);
|
Path clipPath = getClipPath();
|
||||||
|
|
||||||
|
if (clipPath != null && !pathContainsPoint(clipPath, groupMatrix, point)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = getChildCount() - 1; i >= 0; i--) {
|
for (int i = getChildCount() - 1; i >= 0; i--) {
|
||||||
ReactShadowNode child = getChildAt(i);
|
ReactShadowNode child = getChildAt(i);
|
||||||
@@ -92,9 +96,9 @@ public class GroupShadowNode extends RenderableShadowNode {
|
|||||||
|
|
||||||
VirtualNode node = (VirtualNode) child;
|
VirtualNode node = (VirtualNode) child;
|
||||||
|
|
||||||
int viewTag = node.hitTest(point, combinedMatrix);
|
int hitChild = node.hitTest(point, groupMatrix);
|
||||||
if (viewTag != -1) {
|
if (hitChild != -1) {
|
||||||
return (node.isResponsible() || viewTag != child.getReactTag()) ? viewTag : getReactTag();
|
return (node.isResponsible() || hitChild != child.getReactTag()) ? hitChild : getReactTag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import android.graphics.Paint;
|
|||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
|
import android.graphics.Region;
|
||||||
|
|
||||||
import com.facebook.common.logging.FLog;
|
import com.facebook.common.logging.FLog;
|
||||||
import com.facebook.react.bridge.Arguments;
|
import com.facebook.react.bridge.Arguments;
|
||||||
@@ -294,62 +295,35 @@ abstract public class RenderableShadowNode extends VirtualNode {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bitmap bitmap = Bitmap.createBitmap(
|
Matrix pathMatrix = new Matrix(mMatrix);
|
||||||
// mCanvasWidth,
|
|
||||||
// mCanvasHeight,
|
|
||||||
// Bitmap.Config.ARGB_8888);
|
|
||||||
//
|
|
||||||
// Canvas canvas = new Canvas(bitmap);
|
|
||||||
//
|
|
||||||
// if (matrix != null) {
|
|
||||||
// canvas.concat(matrix);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// canvas.concat(mMatrix);
|
|
||||||
//
|
|
||||||
// Paint paint = new Paint();
|
|
||||||
// clip(canvas, paint);
|
|
||||||
// setHitTestFill(paint);
|
|
||||||
// canvas.drawPath(mPath, paint);
|
|
||||||
//
|
|
||||||
// if (setHitTestStroke(paint)) {
|
|
||||||
// canvas.drawPath(mPath, paint);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// canvas.setBitmap(bitmap);
|
|
||||||
// try {
|
|
||||||
// if (bitmap.getPixel(point.x, point.y) != 0) {
|
|
||||||
// return getReactTag();
|
|
||||||
// }
|
|
||||||
// } catch (Exception e) {
|
|
||||||
//
|
|
||||||
// return -1;
|
|
||||||
// } finally {
|
|
||||||
// bitmap.recycle();
|
|
||||||
// }
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setHitTestFill(Paint paint) {
|
if (matrix != null) {
|
||||||
paint.reset();
|
pathMatrix.postConcat(matrix);
|
||||||
paint.setARGB(255, 0, 0, 0);
|
|
||||||
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
|
|
||||||
paint.setStyle(Paint.Style.FILL);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean setHitTestStroke(Paint paint) {
|
|
||||||
if (mStrokeWidth == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
paint.reset();
|
if (pathContainsPoint(mPath, pathMatrix, point)) {
|
||||||
paint.setARGB(255, 0, 0, 0);
|
Path clipPath = getClipPath();
|
||||||
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
|
if (clipPath != null && !pathContainsPoint(clipPath, pathMatrix, point)) {
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
return -1;
|
||||||
paint.setStrokeWidth(mStrokeWidth * mScale);
|
}
|
||||||
paint.setStrokeCap(mStrokeLinecap);
|
|
||||||
paint.setStrokeJoin(mStrokeLinejoin);
|
return getReactTag();
|
||||||
return true;
|
} else{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean pathContainsPoint(Path path, Matrix matrix, Point point) {
|
||||||
|
Path copy = new Path(path);
|
||||||
|
|
||||||
|
copy.transform(matrix);
|
||||||
|
|
||||||
|
RectF rectF = new RectF();
|
||||||
|
copy.computeBounds(rectF, true);
|
||||||
|
Region region = new Region();
|
||||||
|
region.setPath(copy, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));
|
||||||
|
|
||||||
|
return region.contains(point.x, point.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public abstract class VirtualNode extends LayoutShadowNode {
|
|||||||
protected String mName;
|
protected String mName;
|
||||||
|
|
||||||
private SvgViewShadowNode mSvgShadowNode;
|
private SvgViewShadowNode mSvgShadowNode;
|
||||||
|
private Path mCachedClipPath;
|
||||||
|
|
||||||
public VirtualNode() {
|
public VirtualNode() {
|
||||||
mScale = DisplayMetricsHolder.getScreenDisplayMetrics().density;
|
mScale = DisplayMetricsHolder.getScreenDisplayMetrics().density;
|
||||||
@@ -141,8 +142,12 @@ public abstract class VirtualNode extends LayoutShadowNode {
|
|||||||
markUpdated();
|
markUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected @Nullable Path getClipPath() {
|
||||||
|
return mCachedClipPath;
|
||||||
|
}
|
||||||
|
|
||||||
protected @Nullable Path getClipPath(Canvas canvas, Paint paint) {
|
protected @Nullable Path getClipPath(Canvas canvas, Paint paint) {
|
||||||
if (mClipPath != null) {
|
if (mClipPath != null && mCachedClipPath == null) {
|
||||||
VirtualNode node = getSvgShadowNode().getDefinedClipPath(mClipPath);
|
VirtualNode node = getSvgShadowNode().getDefinedClipPath(mClipPath);
|
||||||
|
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
@@ -156,13 +161,13 @@ public abstract class VirtualNode extends LayoutShadowNode {
|
|||||||
default:
|
default:
|
||||||
FLog.w(ReactConstants.TAG, "RNSVG: clipRule: " + mClipRule + " unrecognized");
|
FLog.w(ReactConstants.TAG, "RNSVG: clipRule: " + mClipRule + " unrecognized");
|
||||||
}
|
}
|
||||||
return clipPath;
|
mCachedClipPath = clipPath;
|
||||||
} else {
|
} else {
|
||||||
FLog.w(ReactConstants.TAG, "RNSVG: Undefined clipPath: " + mClipPath);
|
FLog.w(ReactConstants.TAG, "RNSVG: Undefined clipPath: " + mClipPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return getClipPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void clip(Canvas canvas, Paint paint) {
|
protected void clip(Canvas canvas, Paint paint) {
|
||||||
|
|||||||
@@ -259,7 +259,7 @@
|
|||||||
// hitTest delagate
|
// hitTest delagate
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||||
{
|
{
|
||||||
return [self hitTest:point withEvent:event withTransform:CGAffineTransformMakeRotation(0)];
|
return [self hitTest:point withEvent:event withTransform:CGAffineTransformIdentity];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event withTransform:(CGAffineTransform)transform
|
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event withTransform:(CGAffineTransform)transform
|
||||||
|
|||||||
Reference in New Issue
Block a user