18

I would like to display an image (including scroll and zoom functionality). Additionally, I need to add some overlays to the image dynamically. The overlays are in a relationship to the content within the image.

  • If the user scrolls, the overlays should move too
  • If the user zooms, the overlays should not be zoomed but hold their relative position to the image

In other words: I'd like to implement a Map with some markers, but I provide my own map material.

My main question is: How could I do this?

What I have tried so far

  • I tried to implement it within a WebView as it provided the basic zooming and scaling functionality. However, I did not succeed in adding overlays without using Javascript and HTML (what I thought was not a very convenient way of solving the problem)
  • There are projects (i.e. TouchImageView) which are implementing the scroll/zoom functionality but they make it even harder to add own overlay functionality from my point of view.

Questions

Is there a simple solution or approach to my problem?

What is the right way of adding and moving views at runtime in Android? (Usually, I would use a basic layout and play with the margin - would that be best practice?)

Could somebody point me to the right direction, please.

Min. API Level: 10

Sebastian Hojas
  • 4,158
  • 2
  • 27
  • 38
  • 1
    there is no easy way. TouchImageView is fine for starting point. All you need is to change onDraw method to draw your overlays before main image. – Leonidos Jan 02 '13 at 21:14
  • +1 I got the same problem but I implemented it without touch and zoom. – Lalith B Jan 03 '13 at 06:04

5 Answers5

3

I would suggest extending the View class and overriding onDraw method. Take a look at the Canvas API.

You'll probably have an onDraw method that looks like :

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.save();
    canvas.translate(mPosX, mPosY); //position of your actual data
    canvas.scale(mScaleFactor, mScaleFactor); // zoom factor
    map.draw(canvas); //you draw your map here
    canvas.restore(); //go back to saved state 
    //for each marker you have, do the same "save - translate - scale - draw" loop        
}

Since you don't need your markers to be zoomable, you'll probably wont need scale step but you need to calculate their position properly.

Depending on your # of objects etc, you may need to have a more optimized way of drawing your markers (e.g. re-drawing only changed rectangular areas). see View.invalidate(Rect)

yigit
  • 37,683
  • 13
  • 72
  • 58
1

I Think this one can help you

Refer this project Link

it Has a Automatic Scrolling of Image and Zoom a Image When you click On it.

ShreeshaDas
  • 2,042
  • 2
  • 17
  • 36
1

Have you tried subclassing View and handling yourself user gestures? It is my first choice for complex behaviours as such. It should look something like this:

  • In your class extending View you should instantiate the required image and overlays at creation time as Bitmap objects
  • OnScroll event you will calculate how the image and overlays chould be after such scroll, refresh the Bitmaps and invalidate the current view
  • Using a GestureDetector, you can handle pinch events and treat zoom in/zoom out events just as scroll events
  • Remember to always call invalidate after changing your Bitmaps
  • Draw the bitmaps during the onDraw method

Plenty of material about this individual tasks on StackOverflow, let me know if you need adittional help in any of these.

apenasVB
  • 1,463
  • 1
  • 11
  • 21
1

Checkout this example project https://github.com/jzafrilla/AndroidImageHostpot

jzafrilla
  • 1,416
  • 3
  • 18
  • 41
1

After a long time, I found the exact answer to my solution: TileView

Setting up the map view:

@Override
protected void onCreate( Bundle savedInstanceState ) {
  super.onCreate( savedInstanceState );
  TileView tileView = new TileView( this );
  tileView.setSize( 2000, 3000 );  // the original size of the untiled image
  tileView.addDetailLevel( 1f, "tile-%d-%d.png");
  setContentView( tileView );
}

Adding the marker:

tileView.addMarker( someView, 250, 500, -0.5f, -1.0f ); 

Code from the documentation.

Sebastian Hojas
  • 4,158
  • 2
  • 27
  • 38
  • Can I custom TileView? I want to add TileView into a Fragment. This fragment contains both TextView, Button, RelativeLayout and TileView. How could I do this? – nhatpv Apr 04 '16 at 07:22
  • @OneOne I just overrode the TileView class and customised it as a I needed it. Most of the functionality I needed had been offered by the TileView however. – Sebastian Hojas Apr 04 '16 at 10:22
  • I'm in stuck this problem in a long time. Can u give me the example, please? – nhatpv Apr 05 '16 at 09:00
  • Were/are you using a single image or did you end up cutting it into tiles? I tried to go the "big, single image" route and gave the library a `Bitmap` but it doesn't display anything and it looks like you actually need the images as assets. – Neph May 07 '20 at 09:35