0

I'm wondering what would be the best solution to get to the result shown below. Here is what i've found so far:

an ImageView for the forest and a transparent surfaceView (to handle touch) on which I would draw the rectangles? Or... Just One SurfaceView with the image set as background and rectangles directly drawn on...?

For those 2 I've already chosen a RelativeLayout.

Which of those 2 would be the most efficient and easiest to do? Or maybe there is another way which I haven't think about.

In any case thanks for your advice, here is what I tend to...

enter image description here

Antoine
  • 165
  • 1
  • 2
  • 10
  • see: http://stackoverflow.com/questions/16729169/how-to-maintain-multi-layers-of-imageviews-and-keep-their-aspect-ratio-based-on – pskink Aug 26 '13 at 13:42

1 Answers1

1

I've implemented this by placing the image in a RelativeLayout (FrameLayout would work too), and then adding each outlined view programatically. If you know the x and y origin (perhaps as a ratio to the image) and the size for each area, you can easily inflate each view/area (with a black border, transparent center), make it clickable and set a listener, and then set it's origin by adjusting it's margins. You may want to perform all of this after the image has finished laying out:

I put this in onActivityCreated of my Fragment, but other lifecycle methods would work too...

ViewTreeObserver vto = image.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            if (image.getMeasuredHeight() > 0) {
                addHotSpots();
                ViewTreeObserver obs = image.getViewTreeObserver();
                obs.removeGlobalOnLayoutListener(this);
            }
        }

    });

And this is how I actually place all the hotspots/areas:

protected void addHotSpots() {
    HotSpot[] hotSpots = res.hotspots;
    for (HotSpot hs : hotSpots) {
        addHotSpotToImage(hs);

}

private void addHotSpotToImage(HotSpot hs) {

    int height = image.getMeasuredHeight();
    int width = image.getMeasuredWidth();
    //this piece will probably be different for you
    //depending on what you know about the area's intended size/position
    double hsHeightRatio = hs.lr.y - hs.ul.y;
    double hsWidthRatio = hs.lr.x - hs.ul.x;
    double leftMargin = hs.ul.x * width;
    double topMargin = hs.ul.y * height;
    double hsHeight = height * hsHeightRatio;
    double hsWidth = width * hsWidthRatio;
    LayoutInflater vi = (LayoutInflater) image.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View newSpot = vi.inflate(R.layout.question_hotspot, null);

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) hsWidth, (int) hsHeight);
    newSpot.setTag(hs.key);
    newSpot.setFocusable(true);
    newSpot.setClickable(true);
    newSpot.setFocusableInTouchMode(true);
    newSpot.setOnTouchListener(this);

    params.topMargin = (int) topMargin;
    params.leftMargin = (int) leftMargin;
    image.addView(newSpot, params);

}
Sam Dozor
  • 40,335
  • 6
  • 42
  • 42