Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scaling markers #409

Open
sdargutev opened this issue Apr 29, 2017 · 5 comments
Open

Scaling markers #409

sdargutev opened this issue Apr 29, 2017 · 5 comments

Comments

@sdargutev
Copy link

sdargutev commented Apr 29, 2017

Hello,
thank you for the awesome library!
I wonder is there a way to add markers that also scale? Currently markers remain always the same size. I can call marker.setScaleX(scale) and marker.setScaleY(scale) in the onScaleChanged(...) method, but the problem is that in this case the MarkerTapListener does not detect the correct tap location after the scaling. I am guessing, it does not update marker locations as they scale in this case...

Of course setting a click listener directly to the marker view will work, but still, would be nice to see scaling markers. :)

Best regards,
S. Dargutev

@moagrius
Copy link
Owner

moagrius commented May 2, 2017

You're correct, in and Android View system, scaling a View will not affect it's layout or hit area. You can manage those manually, or use HotSpots at those areas. In version 3 this might be a good candidate for a plugin.

@ameron32
Copy link

ameron32 commented Jan 25, 2018

I was trying to produce Markers that scale up and down as well. For anyone looking for a functional solution prior to the version 3 plugin implementation, here is what worked for me.

If you copy/paste the code from MarkerLayout into a new class, say ScalingMarkerLayout, you can create a layout that works. There are only 2 lines of code to change in your new ScalingMarkerLayout class in order to achieve what you want from scaled markers.

from:

  @Override
  protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) {
        ...
        // actual sizes of children
        int actualWidth = child.getMeasuredWidth();
        int actualHeight = child.getMeasuredHeight();
        ...
  }

to:

  @Override
  protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec ) {
        ...
        // actual sizes of children
        int actualWidth = FloatMathHelper.scale( child.getMeasuredWidth(), mScale);
        int actualHeight = FloatMathHelper.scale( child.getMeasuredHeight(), mScale);
        ...
  }

This forces the Markers to scale in the same manner than everything else does. Seems to work perfectly for drawing and touch capture (via the processHit() method) for scaled markers. You'll have to add the ScalingMarkerLayout to your TileView since this is not automatic. If you extend TileView you can add it to your constructor...

  public SuperTileView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    ...
    ScalingMarkerLayout scalingMarkerLayout = new ScalingMarkerLayout(context);
    addView(scalingMarkerLayout, 3); // above mScalingLayout & below mMarkerLayout
    ...
  }

...or to your Activity, Fragment, or ViewGroup, anywhere you have instantiated your TileView...

    TileView tileView = new TileView(context);
    ...
    ScalingMarkerLayout scalingMarkerLayout = new ScalingMarkerLayout(context);
    tileView.addView(scalingMarkerLayout, 3); // above mScalingLayout & below mMarkerLayout

You'll attach a MarkerTapListener to your new scalingMarkerLayout instead of your standard MarkerLayout or TileView. This MarkerTapListener is identical to the original MarkerTapListener in code but you'll have to use separate MarkerTapListeners if you use both scaling and non-scaling markers because the listeners are identical but not interchangeable.

Incorrect:

    // does not apply a MarkerTapListener to the new ScalingMarkerLayout
    tileView.setMarkerTapListener(oldListener); 

Correct:

    // works when newListener is of type ScalingMarkerLayout.MarkerTapListener
    scalingMarkerLayout.setMarkerTapListener(newListener); 

Another thing. You'll need to update the ScalingMarkerLayout when the TileView changes scale. Override onScaleChanged(float scale, float previous) in your SuperTileView to include scalingMarkerLayout.onScaleChanged(scale, previous).

Hope this helps someone out there.

@moagrius
Copy link
Owner

thanks for posting that - we get a ton of questions about scaling markers, so now i have something to link :)

@ameron32
Copy link

In TileView version 3, I got scaling markers working again using a similar logic to before. I can see a few options for sharing it. @moagrius What would you prefer?

1. How would you like me to share it?
I can create a pull request, or share a gist in this thread.

2. How would you like it presented?
It could be a stand-alone plugin ScalingMarkerPlugin, or it could be a modification to MarkerPlugin to allow scalingEnabled as a variable, provided in the constructor.

@moagrius
Copy link
Owner

That's great! Definitely put it in a (new) Plugin and create a PR. please remember to use the existing code style, and if you can update the demo to show functionality, that'd be great.

Thanks for getting this done and sharing.

moagrius added a commit that referenced this issue Dec 15, 2019
Added Scaling Marker Plugin #409
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants