我正在使用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的数组。现在我想让每个引脚都可以点击以启动点击功能。下面的代码正确放置了多个标记请让我知道如何使每个引脚可点击,我想阅读 id 内部点击事件功能并在吐司示例中显示MapPin(1718f,581f,(id)1 )。
修改 PinView.java
public class PinView extends SubsamplingScaleImageView {
private PointF sPin;
ArrayList<MapPin> mapPins;
ArrayList<DrawPin> drawnPins;
Context context;
String tag = getClass().getSimpleName();
public PinView(Context context) {
this(context, null);
this.context = context;
}
public PinView(Context context, AttributeSet attr) {
super(context, attr);
this.context = context;
initialise();
}
public void setPins(ArrayList<MapPin> mapPins) {
this.mapPins = mapPins;
initialise();
invalidate();
}
public void setPin(PointF pin) {
this.sPin = pin;
}
public PointF getPin() {
return sPin;
}
private void initialise() {
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Don't draw pin before image is ready so it doesn't move around during setup.
if (!isReady()) {
return;
}
drawnPins = new ArrayList<>();
Paint paint = new Paint();
paint.setAntiAlias(true);
float density = getResources().getDisplayMetrics().densityDpi;
for (int i = 0; i < mapPins.size(); i++) {
MapPin mPin = mapPins.get(i);
//Bitmap bmpPin = Utils.getBitmapFromAsset(context, mPin.getPinImgSrc());
Bitmap bmpPin = BitmapFactory.decodeResource(this.getResources(), drawable.pushpin_blue);
float w = (density / 420f) * bmpPin.getWidth();
float h = (density / 420f) * bmpPin.getHeight();
bmpPin = Bitmap.createScaledBitmap(bmpPin, (int) w, (int) h, true);
PointF vPin = sourceToViewCoord(mPin.getPoint());
//in my case value of point are at center point of pin image, so we need to adjust it here
float vX = vPin.x - (bmpPin.getWidth() / 2);
float vY = vPin.y - bmpPin.getHeight();
canvas.drawBitmap(bmpPin, vX, vY, paint);
//add added pin to an Array list to get touched pin
DrawPin dPin = new DrawPin();
dPin.setStartX(mPin.getX() - w / 2);
dPin.setEndX(mPin.getX() + w / 2);
dPin.setStartY(mPin.getY() - h / 2);
dPin.setEndY(mPin.getY() + h / 2);
dPin.setId(mPin.getId());
drawnPins.add(dPin);
}
}
public int getPinIdByPoint(PointF point) {
for (int i = drawnPins.size() - 1; i >= 0; i--) {
DrawPin dPin = drawnPins.get(i);
if (point.x >= dPin.getStartX() && point.x <= dPin.getEndX()) {
if (point.y >= dPin.getStartY() && point.y <= dPin.getEndY()) {
return dPin.getId();
}
}
}
return -1; //negative no means no pin selected
}
}
MapPin.java
public class MapPin {
float X, Y;
int id;
public MapPin(float X, float Y, int id) {
this.X = X;
this.Y = Y;
this.id = id;
}
public MapPin() {
}
public float getX() {
return X;
}
public void setX(float X) {
this.X = X;
}
public float getY() {
return Y;
}
public void setY(float Y) {
this.Y = Y;
}
public PointF getPoint() {
return new PointF(this.X, this.Y);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
DrawPin.java
public class DrawPin {
float startX, startY, endX, endY;
int id;
public DrawPin(float startX, float startY, float endX, float endY, int id) {
this.startX = startX;
this.startY = startY;
this.endX = endX;
this.endY = endY;
this.id = id;
}
public DrawPin() {
//empty
}
public float getStartX() {
return startX;
}
public void setStartX(float startX) {
this.startX = startX;
}
public float getStartY() {
return startY;
}
public void setStartY(float startY) {
this.startY = startY;
}
public float getEndX() {
return endX;
}
public void setEndX(float endX) {
this.endX = endX;
}
public float getEndY() {
return endY;
}
public void setEndY(float endY) {
this.endY = endY;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
ExtensionPinFragment
public class ExtensionPinFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(layout.extension_pin_fragment, container, false);
rootView.findViewById(id.next).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
((ExtensionActivity) getActivity()).next();
}
});
PinView imageView = (PinView)rootView.findViewById(id.imageView);
imageView.setImage(ImageSource.asset("squirrel.jpg"));
MapPin mapPin = new MapPin(1718f, 581f, 1);
MapPin mapPin1 = new MapPin(500f, 681f, 2);
ArrayList<MapPin> MapPins = new ArrayList();
MapPins.add(new MapPin(1718f, 581f, 1));
MapPins.add(new MapPin(500f, 681f, 2));
imageView.setPins(MapPins);
// Below on click listener associated with entire image but I want the click event listener for individual pins
imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
((ExtensionActivity) getActivity()).next();
}
}
);
return rootView;
}
}
答案 0 :(得分:4)
目前处理同一问题: 您可以按照以下建议向自定义视图添加gestureDetector和touch侦听器: https://github.com/davemorrissey/subsampling-scale-image-view/wiki/09.-Events
在GestureDetector中覆盖onSingleTapConfirmed()方法并检查点击的触摸坐标是否与引脚坐标匹配(使用sourceToView转换触摸和引脚坐标......)如果是,则处理您想要执行的任何代码。
以下是我的自定义SubsamplingScaleImageView中的代码的一部分,在将引脚添加到视图后调用它:
private void setTouchListener() {
/** https://github.com/davemorrissey/subsampling-scale-image-view/wiki/09.-Events:
* ...you must check that the view is ready with the isReady() method before attempting to convert screen
* coordinates to image coordinates. A NullPointerException may be thrown if you don't. It is safe to override
* onSingleTapUp, onSingleTapConfirmed, onLongPress and onDown from the SimpleOnGestureListener class. If you
* override other methods, you will prevent the view from properly handling double taps, zoom and pan gestures.
*/
final GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (isReady() && deeplinkCoordinates != null) {
PointF tappedCoordinate = new PointF(e.getX(), e.getY());
int blockWidth = deepLinkBitmap.getWidth();
int blockHeight = deepLinkBitmap.getHeight();
// check if deepLinkBitmap is touched
for (PointF deeplink : deeplinkCoordinates) {
PointF deeplinkCoordinate = sourceToViewCoord(deeplink);
int deeplinkX = (int) (deeplinkCoordinate.x - (deepLinkBitmap.getWidth() / 2));
int deeplinkY = (int) (deeplinkCoordinate.y - deepLinkBitmap.getHeight());
// center coordinate -/+ blockWidth actually sets touchable area to 2x icon size
if (tappedCoordinate.x >= deeplinkX - blockWidth && tappedCoordinate.x <= deeplinkX + blockWidth &&
tappedCoordinate.y >= deeplinkY - blockHeight && tappedCoordinate.y <= deeplinkY + blockHeight) {
// App.toast("You tapped on a deeplink!");
}
}
}
return true;
}
});
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return gestureDetector.onTouchEvent(motionEvent);
}
});
}