OsmSharp / ui

The UI components.
http://osmsharp.com/
GNU General Public License v2.0
139 stars 91 forks source link

Panning failure on Android due to presence of markers #267

Open JoeCooper opened 8 years ago

JoeCooper commented 8 years ago

When a user attempts to pan the map by placing a finger upon the screen and dragging it, it fails if the finger initially lands on a map marker.

This is a natural consequence of the way the software is organized with markers existing as buttons attached to the map view; touches do not pass through.

I have a solution for my client which involves using touch-ignorant views as markers (TextViews), forking MapViewSurface and overriding OnTap to check if the tap position falls on any marker in the view.

This requires me to fork OsmSharp's Android UI in order to make OnTap virtual.

Could this be better genericized and integrated into the main branch? Or might this be a no-fix situation?

xivk commented 8 years ago

Has this something to do with you pull-request or is this a different issue?

JoeCooper commented 8 years ago

Nope; different issue. I have it fixed in my project but it's not very generalized. I'll write more later; I am out sick.

xivk commented 8 years ago

OK, get well soon! :+1:

JoeCooper commented 8 years ago

So basically I made the points of interest on the map into non-buttons and wrote a subclass of MapViewSurface that handles the onTap message and cycles through all the map markers to see if one was tap and call the handler.

Basically if your map markers are standard buttons than they'll block touches.

But if they're non-touchable and taps are dispatched by some other agent than it can work.

I think one of my pull requests was about this – exposing something or another to something.

Anyway; this bug is no longer an issue to me so you can close this if you want. I can send you the subclass in question by email if you want.

YordanYanakiev commented 8 years ago

Hello JoeCooper, Please could You share a source about creating markers, since by some reason I can't find a working such. Thanks in advance.

JoeCooper commented 8 years ago

I wrote something like this:

var imageResource = ...;
var image = BitmapFactory.DecodeResource (mapView.Resources, imageResource);
var view = ...; //some subclass of view
var control = new MapControl<MyViewClass> (view, ...Coordinates, MapControlAlignmentType.Center, image.Width, image.Height);
view.SetBackgroundResource (imageResource);
mapView.AddControl (control);

And then in my custom MapViewSurface, I override OnTap, and for each control in MapView.Controls, I check if we ought to interpret it as a hit. My custom MapViewSurface then dispatches an event to a multicast delegate.

public override bool OnTap (TapGestureDetector detector)
{
    var hitAnything = false;
    var x = detector.X;
    var y = detector.Y;

    foreach (var marker in MapView.Controls) {
        var view = marker.BaseView;
        var hitRect = new Rect ();
        view.GetHitRect (hitRect);
        if (hitRect.Contains ((int) x, (int) y)) {
            ... //Dispatch to a multicast delegate or something
            hitAnything = true;
            break;
        }
    }
    return hitAnything || base.OnTap (detector); // Short circuit evaluation
}
YordanYanakiev commented 8 years ago

I mean - how you actually creating the markers and adding them to the map ?

JoeCooper commented 8 years ago

See above. The first section, ending with mapView.AddControl. A "marker" is a particular kind of control with properties we don't want; they're controls which are also buttons.