简体   繁体   English

子采样比例图像视图 - 使图像视图上的引脚标记可单击

[英]Subsampling scale image view - make pin markers clickable on Imageview

I'm using Dave Morrissey's Subsampling Scale Image View. 我正在使用Dave Morrissey的子采样比例图像视图。 I modified the Pinview example (as shown here: https://github.com/davemorrissey/subsampling-scale-image-view/blob/master/sample/src/com/davemorrissey/labs/subscaleview/sample/extension/views/PinView.java ) to support array of pin's. 我修改了Pinview示例(如下所示: https//github.com/davemorrissey/subsampling-scale-image-view/blob/master/sample/src/com/davemorrissey/labs/subscaleview/sample/extension/views/ PinView.java )支持pin的数组。 Now I want to make each pin clickable to set off an on click function. 现在我想让每个引脚都可以点击以启动点击功能。 Below code places multiple markers correctly. 下面的代码正确放置了多个标记 Please let me know how to make each pin's clickable and I want to read the id inside click event function and display in a toast example MapPin(1718f, 581f, (id) 1 ). 请让我知道如何使每个引脚可点击,我想读取内部点击事件功能的id并在吐司示例MapPin(1718f,581f, (id)1 )中显示。

Modified PinView.java 修改了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 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 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 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;
    }
}

Currently working on the same issue: You could add a gestureDetector and a touch listener to your custom view as suggested in: https://github.com/davemorrissey/subsampling-scale-image-view/wiki/09.-Events 目前正在处理同一问题:您可以按照以下建议添加一个gestureDetector和一个触摸侦听器到您的自定义视图: https//github.com/davemorrissey/subsampling-scale-image-view/wiki/09.-Events

In the GestureDetector override the onSingleTapConfirmed() method and check if the tapped touch coordinate matches a pin coordinate (use sourceToView for transforming touch and pin coordinates...) and if so handle whatever code you want to be executed. 在GestureDetector中覆盖onSingleTapConfirmed()方法并检查点击的触摸坐标是否与引脚坐标匹配(使用sourceToView转换触摸和引脚坐标......)如果是,则处理您想要执行的任何代码。

Here is part of the code in my custom SubsamplingScaleImageView which gets called after the pin have been added to the view: 以下是我的自定义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);
        }
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM