Open sdargutev opened 7 years ago
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.
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.
thanks for posting that - we get a ton of questions about scaling markers, so now i have something to 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.
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.
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