Marker click event in android map using osm - java

i am using following code for creating marker(bitmap),how to add click event for marker. i use graphhopper android for OSM map
startMarker = createMarker(startPoint, R.drawable.marker_departure); layers.add(startMarker);
add use createMarker method
public Marker createMarker(LatLong p, int resource) {
Drawable drawable = activity.getResources().getDrawable(resource);
Bitmap bitmap = AndroidGraphicFactory.convertToBitmap(drawable);
return new Marker(p, bitmap, 0, -bitmap.getHeight() / 2);
}
and how to add text near to marker
thanks in advance

Try with this, may be this will help full.
layers.setOnMarkerClickListener(new OnMarkerClickListener()
{
#Override
public boolean onMarkerClick(Marker arg0) {
//Your stuff
});

i use following code its works for me
MyMarker frommarker = newMyMarker(activity,newLatLong(fl.latitude,fl.longitude), AndroidGraphicFactory.convertToBitmap(activity.getResources().getDrawable(R.drawable.marker_departure)), 0, 0);
mapView.getLayerManager().getLayers().add(frommarker);
and mymarker class
public class MyMarker extends Marker {
private Context ctx;
public MyMarker(Context ctx, LatLong latLong, Bitmap bitmap, int horizontalOffset,
int verticalOffset) {
super(latLong, bitmap, horizontalOffset, verticalOffset);
this.ctx = ctx;
}
#Override
public boolean onTap(LatLong tapLatLong, Point layerXY, Point tapXY) {
if (this.contains(layerXY, tapXY)) {
}
}

Related

Android.Util.Property Class Implemention in C#

I have been banging my head for days to find some help but maybe I am not looking at the right place.
I am following this article to replicate Twitter like button animation (I don't want to use rebuilt libraries) - http://frogermcs.github.io/twitters-like-animation-in-android-alternative/
I have a Custom View called LikeButtonView
public class LikeButtonView : FrameLayout, View.IOnClickListener
{
private static DecelerateInterpolator DECCELERATE_INTERPOLATOR = new DecelerateInterpolator();
private static AccelerateDecelerateInterpolator ACCELERATE_DECELERATE_INTERPOLATOR = new AccelerateDecelerateInterpolator();
private static OvershootInterpolator OVERSHOOT_INTERPOLATOR = new OvershootInterpolator(4);
private ImageView ivStar;
private DotsView vDotsView;
private AnimatorSet animatorSet;
public LikeButtonView(Context context, IAttributeSet attrs) :
base(context, attrs)
{
Initialize();
}
public LikeButtonView(Context context, IAttributeSet attrs, int defStyle) :
base(context, attrs, defStyle)
{
Initialize();
}
public void OnClick(View v)
{
vDotsView.setCurrentProgress(0);
animatorSet = new AnimatorSet();
ObjectAnimator starScaleYAnimator = ObjectAnimator.OfFloat(ivStar, ImageView.ScaleYs, 0.2f, 1f);
starScaleYAnimator.SetDuration(350);
starScaleYAnimator.StartDelay = (250);
starScaleYAnimator.SetInterpolator(OVERSHOOT_INTERPOLATOR);
ObjectAnimator starScaleXAnimator = ObjectAnimator.OfFloat(ivStar, ImageView.ScaleXs, 0.2f, 1f);
starScaleXAnimator.SetDuration(350);
starScaleXAnimator.StartDelay = (250);
starScaleXAnimator.SetInterpolator(OVERSHOOT_INTERPOLATOR);
ObjectAnimator dotsAnimator = ObjectAnimator.OfFloat(vDotsView, DotsView.DOTS_PROGRESS, 0.2f, 1f);
dotsAnimator.SetDuration(900);
dotsAnimator.StartDelay = (50);
dotsAnimator.SetInterpolator(ACCELERATE_DECELERATE_INTERPOLATOR);
animatorSet.PlayTogether(
starScaleYAnimator,
starScaleXAnimator,
dotsAnimator
);
animatorSet.Start();
}
private void Initialize()
{
var INF = LayoutInflater.From(Context).Inflate(Resource.Layout.view_like_button, this, true);
ivStar = INF.FindViewById<ImageView>(Resource.Id.ivStar);
vDotsView = INF.FindViewById<DotsView>(Resource.Id.vDotsView);
SetOnClickListener(this);
}
}
I am also using private DotsView vDotsView which is another custom view, which is a C# Replica of this view https://github.com/frogermcs/LikeAnimation/blob/master/app/src/main/java/frogermcs/io/likeanimation/DotsView.java
In the above link, right at the end, I see the following
public static final Property<DotsView, Float> DOTS_PROGRESS = new Property<DotsView, Float>(Float.class, "dotsProgress") {
#Override
public Float get(DotsView object) {
return object.getCurrentProgress();
}
#Override
public void set(DotsView object, Float value) {
object.setCurrentProgress(value);
}
};
It is Android.Util.Property getting used to get and set the progress
ObjectAnimator dotsAnimator = ObjectAnimator.OfFloat(vDotsView, DotsView.DOTS_PROGRESS, 0.2f, 1f);
I am lost right here, I do not know how to implement this in C#? I have been trying different things but no luck with implementing public static final Property<DotsView, Float> DOTS_PROGRESS with exact parameters.
If anyone can help would be highly appreciated.
If this helps anyone, we can do something like the following
[Register("DOTS_PROGRESS")]
public static Property DotsProgress {
get {
JniObjectReference objectValue = _members.get_StaticFields().GetObjectValue("DOTS_PROGRESS.Landroid/util/Property;");
return Object.GetObject<Property>(objectValue.get_Handle(), 1);
}
}
Found this package which was converted from java to C#
https://www.fuget.org/packages/Karamunting.Android.HanksZyh.SmallBang/1.2.2/lib/monoandroid81/SmallBang.dll/Hanks.Library.Bang/DotsView?code=true

Android - How to call method in custom View from Main Activity?

I have created a custom View that will display a circle (the idea is that the user will be able to interact with this "ball" in various ways)
From my main activity class, I want to adjust some of the "ball's" properties, in this case change its color.
My problem is that nothing happens (no errors either, the app runs but doesn't do what I want) when I try to call the various methods from my MainActivity class, but if I do it from CircleView class, it works (for example changing the color upon touch)
Here is my custom View class (CircleView.java):
public class CircleView extends View {
private int circleColor = Color.GREEN;
private Paint paint;
public CircleView(Context context) {
super(context);
init(context, null);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_SCROLL:
this.circleColor = setRandomColor();
invalidate();
break;
case MotionEvent.ACTION_DOWN:
this.circleColor = setRandomColor();
invalidate();
break;
}
return super.onTouchEvent(event);
}
public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
paint = new Paint();
paint.setAntiAlias(true);
}
public void setCircleColor(int circleColor) {
this.circleColor = circleColor;
invalidate();
}
public int setRandomColor() {
Random random = new Random();
int randomColor = Color.argb(255, random.nextInt(), random.nextInt(), random.nextInt());
return randomColor;
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//...
//someXvalue, someYvalue, someRadius are being set here
//...
paint.setColor(circleColor);
canvas.drawCircle(someXvalue, someYvalue, someRadius, paint);
}
}
And here is my MainActivity.java class:
public class MainActivity extends Activity implements
GestureDetector.OnGestureListener {
private GestureDetectorCompat mDetector;
CircleView circle;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDetector = new GestureDetectorCompat(this, this);
circle = new CircleView(this);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
#Override
public boolean onDown(MotionEvent event) {
return true;
}
#Override
public boolean onSingleTapConfirmed(MotionEvent event) {
circle.setCircleColor(circle.setRandomColor(0));
circle.invalidate();
return true;
}
}
I am new to Android development, and Java as well. I realize it could be something with the Context, which is something I have not fully understood yet. Could also be something with the TouchEvents. I am sure that someone out there can see my mistake. Any help is appreciated.
your circle view is not a part of activity's layout , it's just a object in memory which has no link to your activity screen so solutions
1.) Either set circle as Activity's view
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDetector = new GestureDetectorCompat(this, this);
circle = new CircleView(this);
setContentView(circle);
}
2.) you can create your <yourpackagename.CircleView ...attributes .../> tag in your activity_main.xml and then use findViewById to initialize it in your activity.
1)If all you want to do with gestures is on tap, just implement an onClickListener on your View instead.
2)You aren't actually using the GestureDetector anywhere. The way it works is you set an onTouchListener for the view you want to get gestures on, and send the events to the gesture detector. You aren't ever sending data for any view to the detector, so it will never do anything.
3)Not a bug just an oddness- why circle.setColor(circle.setRandomColor())? I would expect a function named setXXX to actually set XXX, rather than having to do it yourself later. Not following that convention will work, but make debugging and maintenance hard.
Edit: Also what #Pavneet_Singh said- your circle isn't in your layout anywhere, so it won't be on screen.

Using onSizeChanged in Drawable class

I have created a custom class which extends Drawable. I'm trying to get the dimensions of the Drawable by using onSizeChanged() as follow
public class Circle extends Drawable {
...
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
super.onSizeChanged(xNew, yNew, xOld, yOld);
}
}
But I'm getting an error saying that "Method does not override from the superclass". What do I do to fix it?
Thanks a lot to Michael Spitsin for this answer. To get the dimensions of the layout which the drawable is attached to, use the following code
#Override
protected void onBoundsChange(Rect bounds) {
mHeight = bounds.height();
mWidth = bounds.width();
}
If we go to View source code and in Drawable source code, we will see next things:
In View.setBackgroundDrawable(Drawable) if we pass not null, than field mBackground (is is responsible to store background drawable) is updated.
If we will try to find usages of method Drawable.onBoundsChanged() then we will see that it is mainly used in Drawable.setBounds method. And if we will find usages of it, we will see next snippet in View.class:
private void drawBackground(Canvas canvas) {
final Drawable background = mBackground;
if (background == null) {
return;
}
if (mBackgroundSizeChanged) {
background.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
mBackgroundSizeChanged = false;
rebuildOutline();
}
//draw background through background.draw(canvas)
}
Thus, using of onBoundsChanged callback is accepted for your task.

Osmdroid Bonuspack - MyLocationNewOverlay

I currently have a couple of features that are causing a few problems that where originally working but after changing some things around are now producing errors. Using Android Studio which allowed me to look at previous versions of the code but to no avail.
Anyway I have a MyLocationNewOverlay declared globally like so:
MyLocationNewOverlay location_overlay;
Which gets initiated when the user navigates to the activity with the map:
map = (MapView) findViewByID(R.id.map);
map.setVisibility(MapView.VISIBLE);
<..some working code that sets the tile source and the center..>
location_overlay = new MyLocationNewOverlay(getApplicationContext(), map);
location_overlay.enableMyLocation();
location_overlay.setDrawAccuracyEnabled(true);
map.getOverlays().add(location_overlay);
map.invalidate();
When it was working this code displayed a little human marker with the accuracy circle around it but now it doesn't even though it doesn't produce any errors. Iv'e tried the now decrepit MyLocationOverlay which didn't work either.
The second issue lies within an 'onClick' method on a button that supposed to focus the map on the users current location, this also used to work.
public void onBtnFocusOnMe(View view){
GeoPoint gp = new GeoPoint(location_overlay.getMyLocation());
if(gp != null){
mapController.animateTo(gp);
mapController.zoomTo(16);
}
}
Which produces a null pointer error on GeoPoint gp = new GeoPoint(location_overlay.getMyLocation());
How I normally overlay some items is like this, it is not directly your solution but you can maybe extract something useful from here:
public void showStartGoalMarkers(GeoPoint start, GeoPoint goal) {
List<OverlayItem> mStartGoalItems = new ArrayList<>();
OverlayItem startItem = new OverlayItem("", "", start);
Drawable newMarker = mMapView.getContext().getResources().getDrawable(R.drawable.ic_start);
startItem.setMarker(newMarker);
mStartGoalItems.add(startItem);
OverlayItem goalItem = new OverlayItem("", "", goal);
Drawable newMarker2 = mMapView.getContext().getResources().getDrawable(R.drawable.ic_end);
goalItem.setMarker(newMarker2);
mStartGoalItems.add(goalItem);
mMapView.getOverlays().add(new ItemizedIconOverlay<OverlayItem>(mStartGoalItems, new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemSingleTapUp(int index, OverlayItem item) {
return false;
}
#Override
public boolean onItemLongPress(int index, OverlayItem item) {
return false;
}
}, mMapView.getResourceProxy()));
}
and in the end you invalidate the map view. Hope it helps.
EDIT: the code for marking the current location and which also updates the current position when a new location is passed:
private void markMyLocation(Location location) {
mOverlayItems.add(0, new OverlayItem("", "", new GeoPoint(location)));
if (mMyLocationOverlay == null) {
mMyLocationOverlay = new MyLocationOverlay(mOverlayItems, new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemSingleTapUp(int index, OverlayItem item) {
IMapController mapController = mMapView.getController();
mapController.setCenter(item.getPoint());
mapController.setZoom(mMapView.getMaxZoomLevel());
return true;
}
#Override
public boolean onItemLongPress(int index, OverlayItem item) {
return false;
}
}, mMapView.getResourceProxy());
mMapView.getOverlays().add(mMyLocationOverlay);
mMapView.getController().setZoom(16);
} else {
IMapController mapController = mMapView.getController();
mapController.setCenter(mOverlayItems.get(0).getPoint());
mMapView.invalidate();
}
}
The MyLocationOverlay class:
public class MyLocationOverlay extends ItemizedIconOverlay<OverlayItem> {
List<OverlayItem> mMyLocation;
int mResourceId;
public MyLocationOverlay(List<OverlayItem> pList,
OnItemGestureListener<OverlayItem> pOnItemGestureListener,
ResourceProxy pResourceProxy) {
super(pList, pOnItemGestureListener, pResourceProxy);
this.mMyLocation = pList;
this.mResourceId = R.drawable.my_location;
}
#Override
public void draw(Canvas canvas, MapView mapview, boolean arg2) {
super.draw(canvas, mapview, true);
if (!mMyLocation.isEmpty()) {
IGeoPoint geoPointLocation = mMyLocation.get(0).getPoint();
Point out = new Point();
mapview.getProjection().toPixels(geoPointLocation, out);
Bitmap bm = BitmapFactory.decodeResource(mapview.getResources(),
mResourceId);
canvas.drawBitmap(bm,
out.x - bm.getWidth() / 2, //shift the bitmap center
out.y - bm.getHeight() / 2, //shift the bitmap center
null);
}
}
#Override
public boolean onSingleTapUp(MotionEvent event, MapView mapView) {
// TODO Auto-generated method stub
//return super.onSingleTapUp(event, mapView);
return true;
}
Basically what I do is I overwrite the single item in the ArrayList mOverlayItems when the method is called and invalidate the map.

Line appears in OverlayItem on Google Maps

I'm using an ItemizedOverlay on a Google Maps in an Android application. My extension of ItemizedOverlay is shown below.
The strange thing is I see a small line from about the 8 o'clock position to the 2 o'clock position in every occurrence of the overlay. The overlay is a png that is in my application resources (which obviously doesn't have the strange line). I've attached an example of the raw png overlay (R.drawable.green) here:
And here is what I see in the android app:
(You kind of have to look closely to see the gray line I'm talking about. It is under the green dots and under the little airplane icon.)
The overlay is added as follows:
ReportOverlay itemizedoverlay = new ReportOverlay(getResources().getDrawable(R.drawable.green),mContext);
GeoPoint point = new GeoPoint(pr.getLat(),pr.getLng());
OverlayItem overlayitem = new OverlayItem(point, pr.getReport(),pr.getReport());
itemizedoverlay.addOverlay(overlayitem);
Any idea where this mystery line in the overlay is coming from?!
public class ReportOverlay extends ItemizedOverlay<OverlayItem> {
protected ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
Context mContext;
public ReportOverlay(Drawable defaultMarker) {
super(boundCenter(defaultMarker));
}
public ReportOverlay(Drawable defaultMarker, Context context) {
super(boundCenter(defaultMarker));
mContext = context;
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
#Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
#Override
public int size() {
return mOverlays.size();
}
}
As MH suggested, it was indeed the shadow that I was seeing. Turning it off fixed the issue.

Categories