简体   繁体   English

带有叠加层的Android可缩放/可滚动ImageView

[英]Android zoomable/scrollable ImageView with overlays

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. 换句话说:我想用一些标记来实现Map,但我提供了自己的地图材质。

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. 我尝试在WebView中实现它,因为它提供了基本的缩放和缩放功能。 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) 但是,我没有成功添加叠加而不使用Javascript和HTML(我认为这不是解决问题的一种非常方便的方法)
  • There are projects (ie TouchImageView ) which are implementing the scroll/zoom functionality but they make it even harder to add own overlay functionality from my point of view. 有些项目(即TouchImageView )正在实现滚动/缩放功能,但是从我的角度来看,它们更难以添加自己的叠加功能。

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? 在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 API等级:10

I would suggest extending the View class and overriding onDraw method. 我建议扩展View类并重写onDraw方法。 Take a look at the Canvas API . 看看Canvas API

You'll probably have an onDraw method that looks like : 您可能有一个onDraw方法,如下所示:

@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 (eg re-drawing only changed rectangular areas). 根据您的#对象等,您可能需要更优化的方式来绘制标记(例如,仅重新绘制已更改的矩形区域)。 see View.invalidate(Rect) 请参阅View.invalidate(Rect)

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. 它具有自动滚动图像和缩放图像单击它时。

Have you tried subclassing View and handling yourself user gestures? 您是否尝试过子类化View并处理自己的用户手势? 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 在扩展View的类中,您应该在创建时将所需的图像和叠加实例化为Bitmap对象
  • OnScroll event you will calculate how the image and overlays chould be after such scroll, refresh the Bitmaps and invalidate the current view 在OnScroll事件中,您将计算在此类滚动后图像和叠加层的形式,刷新位图并使当前视图无效
  • Using a GestureDetector, you can handle pinch events and treat zoom in/zoom out events just as scroll events 使用GestureDetector,您可以处理夹点事件并像处理滚动事件一样处理放大/缩小事件
  • Remember to always call invalidate after changing your Bitmaps 请记住在更改位图后始终调用invalidate
  • Draw the bitmaps during the onDraw method 在onDraw方法中绘制位图

Plenty of material about this individual tasks on StackOverflow, let me know if you need adittional help in any of these. 关于StackOverflow上这些单独任务的大量资料,请告诉我您是否需要其中任何一个的adittional帮助。

After a long time, I found the exact answer to my solution: TileView 很长一段时间后,我找到了解决方案的确切答案: 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. 文档中的代码。

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

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