如何使图钉标记在 Imageview 上可点击
How to make a pin markers clickable on Imageview
我正在使用 Dave Morrissey 的子采样比例图像视图。我正在使用他的 Pinview 示例(如此处所示:https://github.com/davemorrissey/subsampling-scale-image-view/blob/master/sample/src/com/davemorrissey/labs/subscaleview/sample/extension/views/PinView.java)
我所做的不同之处在于,我创建了一个位图数组列表,这些位图是 Pin。但我想让每个引脚都可以点击以触发点击功能。我知道无法点击位图。我在地图图像上有多个图钉,并且希望每个图钉都与一个对象相关联。
完成此任务的最佳方法是什么?
注意:我确实重写了 Pinview class 中的 setOnClickListener 方法,但是所有被删除的图钉都关联到同一个对象。然后清除 1 个引脚将清除所有引脚。
存储位图、点F和点名称的模型:
public class CategoryPoint {
private String category;
private Bitmap image;
private PointF pointF;
public CategoryPoint(String category, Bitmap image, PointF pointF) {
this.category = category;
this.image = image;
this.pointF = pointF;
}
// getters/setters
}
视图如下所示:
public class PinsView extends SubsamplingScaleImageView {
private OnPinClickListener onPinClickListener;
private final Paint paint = new Paint();
private List<CategoryPoint> categoryPoints;
public PinsView(Context context) {
this(context, null);
}
public PinsView(Context context, AttributeSet attr) {
super(context, attr);
categoryPoints = new ArrayList<>();
initTouchListener();
}
public void addCategories(List<CategoryPoint> categoryPoints) {
this.categoryPoints = categoryPoints;
invalidate();
}
public void removeCategories(List<CategoryPoint> categoryPoints) {
this.categoryPoints.removeAll(categoryPoints);
invalidate();
}
public void removeAllCategories() {
this.categoryPoints.clear();
invalidate();
}
public void setOnPinClickListener(OnPinClickListener listener) {
onPinClickListener = listener;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isReady()) {
return;
}
paint.setAntiAlias(true);
for (CategoryPoint categoryPoint: categoryPoints) {
Bitmap pinIcon = categoryPoint.getImage();
if (categoryPoint.getPointF() != null && categoryPoint.getImage() != null) {
PointF point = sourceToViewCoord(categoryPoint.getPointF());
float vX = point.x - (pinIcon.getWidth()/2);
float vY = point.y - pinIcon.getHeight();
canvas.drawBitmap(pinIcon, vX, vY, paint);
}
}
}
private void initTouchListener() {
GestureDetector gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (isReady() && categoryPoints != null) {
PointF tappedCoordinate = new PointF(e.getX(), e.getY());
Bitmap clickArea = categoryPoints.get(0).getImage();
int clickAreaWidth = clickArea.getWidth();
int clickAreaHeight = clickArea.getHeight();
for (CategoryPoint categoryPoint : categoryPoints) {
PointF categoryCoordinate = sourceToViewCoord(categoryPoint.getPointF());
int categoryX = (int) (categoryCoordinate.x);
int categoryY = (int) (categoryCoordinate.y - clickAreaHeight / 2);
if (tappedCoordinate.x >= categoryX - clickAreaWidth / 2
&& tappedCoordinate.x <= categoryX + clickAreaWidth / 2
&& tappedCoordinate.y >= categoryY - clickAreaHeight / 2
&& tappedCoordinate.y <= categoryY + clickAreaHeight / 2) {
onPinClickListener.onPinClick(categoryPoint);
break;
}
}
}
return true;
}
});
setOnTouchListener((v, event) -> gestureDetector.onTouchEvent(event));
}
}
片段:
pinView.setOnImageEventListener(this);
pinView.setOnPinClickListener(this);
// implementation
我正在使用 Dave Morrissey 的子采样比例图像视图。我正在使用他的 Pinview 示例(如此处所示:https://github.com/davemorrissey/subsampling-scale-image-view/blob/master/sample/src/com/davemorrissey/labs/subscaleview/sample/extension/views/PinView.java)
我所做的不同之处在于,我创建了一个位图数组列表,这些位图是 Pin。但我想让每个引脚都可以点击以触发点击功能。我知道无法点击位图。我在地图图像上有多个图钉,并且希望每个图钉都与一个对象相关联。
完成此任务的最佳方法是什么?
注意:我确实重写了 Pinview class 中的 setOnClickListener 方法,但是所有被删除的图钉都关联到同一个对象。然后清除 1 个引脚将清除所有引脚。
存储位图、点F和点名称的模型:
public class CategoryPoint {
private String category;
private Bitmap image;
private PointF pointF;
public CategoryPoint(String category, Bitmap image, PointF pointF) {
this.category = category;
this.image = image;
this.pointF = pointF;
}
// getters/setters
}
视图如下所示:
public class PinsView extends SubsamplingScaleImageView {
private OnPinClickListener onPinClickListener;
private final Paint paint = new Paint();
private List<CategoryPoint> categoryPoints;
public PinsView(Context context) {
this(context, null);
}
public PinsView(Context context, AttributeSet attr) {
super(context, attr);
categoryPoints = new ArrayList<>();
initTouchListener();
}
public void addCategories(List<CategoryPoint> categoryPoints) {
this.categoryPoints = categoryPoints;
invalidate();
}
public void removeCategories(List<CategoryPoint> categoryPoints) {
this.categoryPoints.removeAll(categoryPoints);
invalidate();
}
public void removeAllCategories() {
this.categoryPoints.clear();
invalidate();
}
public void setOnPinClickListener(OnPinClickListener listener) {
onPinClickListener = listener;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isReady()) {
return;
}
paint.setAntiAlias(true);
for (CategoryPoint categoryPoint: categoryPoints) {
Bitmap pinIcon = categoryPoint.getImage();
if (categoryPoint.getPointF() != null && categoryPoint.getImage() != null) {
PointF point = sourceToViewCoord(categoryPoint.getPointF());
float vX = point.x - (pinIcon.getWidth()/2);
float vY = point.y - pinIcon.getHeight();
canvas.drawBitmap(pinIcon, vX, vY, paint);
}
}
}
private void initTouchListener() {
GestureDetector gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (isReady() && categoryPoints != null) {
PointF tappedCoordinate = new PointF(e.getX(), e.getY());
Bitmap clickArea = categoryPoints.get(0).getImage();
int clickAreaWidth = clickArea.getWidth();
int clickAreaHeight = clickArea.getHeight();
for (CategoryPoint categoryPoint : categoryPoints) {
PointF categoryCoordinate = sourceToViewCoord(categoryPoint.getPointF());
int categoryX = (int) (categoryCoordinate.x);
int categoryY = (int) (categoryCoordinate.y - clickAreaHeight / 2);
if (tappedCoordinate.x >= categoryX - clickAreaWidth / 2
&& tappedCoordinate.x <= categoryX + clickAreaWidth / 2
&& tappedCoordinate.y >= categoryY - clickAreaHeight / 2
&& tappedCoordinate.y <= categoryY + clickAreaHeight / 2) {
onPinClickListener.onPinClick(categoryPoint);
break;
}
}
}
return true;
}
});
setOnTouchListener((v, event) -> gestureDetector.onTouchEvent(event));
}
}
片段:
pinView.setOnImageEventListener(this);
pinView.setOnPinClickListener(this);
// implementation