Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set click event for each path #29

Open
tracyallen opened this issue Jun 16, 2016 · 3 comments
Open

set click event for each path #29

tracyallen opened this issue Jun 16, 2016 · 3 comments

Comments

@tracyallen
Copy link

if there are many path in xxx.svg file,
how can i set click event for each path ?

@abdallaadelessa
Copy link

public class ImageMapTestActivity extends Activity {
private ImageView mImageMap;
private Sharp mSvg;
private Toast toast;
private RectF canvasBounds;
private PhotoViewAttacher mAttacher;
Set regions = new HashSet();
private String selectedId;

// --------------->

@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;
    }
}

}

@ajilo297
Copy link

@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.

@asadaltaf583
Copy link

can you guys explain PhotoViewAttacher? is it library?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants