Open tracyallen opened 8 years ago
public class ImageMapTestActivity extends Activity {
private ImageView mImageMap;
private Sharp mSvg;
private Toast toast;
private RectF canvasBounds;
private PhotoViewAttacher mAttacher;
Set
// --------------->
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
toast = Toast.makeText(ImageMapTestActivity.this, "", Toast.LENGTH_SHORT);
mImageMap = (ImageView) findViewById(R.id.map);
mAttacher = new PhotoViewAttacher(mImageMap);
mAttacher.setMaximumScale(10f);
mAttacher.setOnPhotoTapListener(new PhotoViewAttacher.OnPhotoTapListener() {
@Override
public void onPhotoTap(View view, float x, float y) {
boolean canHandleClick = false;
PointF sCoord = toImageBound(x, y);
for(Region region : regions) {
RectF rectF = new RectF();
region.path.computeBounds(rectF, true);
if(region.elementBounds.contains(sCoord.x, sCoord.y)) {
canHandleClick = true;
selectedId = region.id;
}
}
if(canHandleClick) refreshSvg();
}
});
mSvg = Sharp.loadResource(getResources(), R.raw.cartman);
refreshSvg();
}
// --------------->
private void refreshSvg() {
mSvg.setOnElementListener(new OnSvgElementListener() {
@Nullable
@Override
public void onSvgStart(@NonNull Canvas canvas, @Nullable RectF bounds) {
}
@Override
public void onSvgEnd(@NonNull Canvas canvas, @Nullable RectF bounds) {
}
@Override
public <T> T onSvgElement(@Nullable String id, @NonNull T element, @Nullable RectF elementBounds, @NonNull Canvas canvas, @Nullable RectF canvasBounds, @Nullable Paint paint) {
if(paint != null && paint.getStyle() == Paint.Style.FILL) {
ImageMapTestActivity.this.canvasBounds = canvasBounds;
regions.add(new Region(id, (Path) element, new RectF(elementBounds)));
if(selectedId != null && selectedId.equals(id)) {
paint.setColor(Color.BLACK);
}
}
return element;
}
@Override
public <T> void onSvgElementDrawn(@Nullable String id, @NonNull T element, @NonNull Canvas canvas, @Nullable Paint paint) {
}
});
mSvg.getSharpPicture(new Sharp.PictureCallback() {
@Override
public void onPictureReady(SharpPicture picture) {
Drawable drawable = picture.getDrawable(mImageMap);
mImageMap.setImageDrawable(drawable);
//mAttacher.update();
}
});
}
// --------------->
@NonNull
private PointF toImageBound(float x, float y) {
return new PointF(x * canvasBounds.right, y * canvasBounds.bottom);
}
public static class Region {
public String id;
public RectF elementBounds;
public Path path;
public Region(String id, Path path, RectF elementBounds) {
this.id = id;
this.path = path;
this.elementBounds = elementBounds;
}
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
Region region = (Region) o;
return id != null ? id.equals(region.id) : region.id == null;
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
}
}
@abdallaadelessa I have got to admit that without the block of code you provided, I would have been stuck at detecting click events on different paths for a long time. So thanks for that.
However I think that code inside the onPhotoTapListener
can be improved slightly. Right now, the touch events are detected based on whether the touch falls within the bounds of the path. While this may work for most cases involving convex paths, it causes problems when the path bounds of different paths overlap. I have changed the code a little to overcome the problem
PhotoViewAttacher attach = new PhotoViewAttacher(mapView);
attach.setOnPhotoTapListener(new OnPhotoTapListener() {
@Override
public void onPhotoTap(ImageView view, float x, float y) {
boolean canHandleClick = false;
PointF cPoint = toImageBound(x, y);
for (Region region : regions) {
Path rPath = region.path;
Path tapPath = new Path();
tapPath.addRect(cPoint.x - 0.25f, cPoint.y - 0.25f, cPoint.x + 0.25f, cPoint.y + 0.25f, Path.Direction.CW);
Path path = new Path();
boolean intersects = path.op(tapPath, rPath, Path.Op.INTERSECT);
if (intersects && !path.isEmpty()) {
canHandleClick = true;
selectedId = region.id;
break;
}
}
if(canHandleClick) refreshSVG();
}
});
I am not sure if this is memory efficient, but it does the job for me and I hope it helps someone out there.
can you guys explain PhotoViewAttacher? is it library?
if there are many path in xxx.svg file, how can i set click event for each path ?