Create custom bitmap marker with android map API V2 - android

I'm trying to Create custom bitmap marker and place it at particular Lat-Lng on google Map, for that I have written the following code--
My custom marker view is (user_prof_pic_marker.xml)--
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="#dimen/sz_sixty_five"
android:layout_height="#dimen/sz_sixty_five"
android:layout_centerInParent="true"
android:src="#drawable/map_marker" />
<com.wikiNews.custom.CircleImageView
android:id="#+id/myImage"
android:layout_width="#dimen/sz_fifty"
android:layout_height="#dimen/sz_fifty"
android:layout_centerInParent="true"
android:src="#drawable/profiledefaultimg" />
</RelativeLayout>
This is how I am setting image to the custom view--
View myUserMarkerLayout = getLayoutInflater().inflate(R.layout.user_prof_pic_marker, null);
myUserImageView = (CircleImageView) myUserMarkerLayout.findViewById(R.id.myImage);
myUserImageView.setBorderColor(Color.WHITE);
myUserImageView.setBorderWidth(2);
//String strPic = UserDetails.getInstance().getCurrentProfilePic();
if(UserDetails.getInstance().getCurrentProfilePic()!=null && !UserDetails.getInstance().getCurrentProfilePic().isEmpty())
{
Picasso.with(this).load(UserDetails.getInstance().getCurrentProfilePic()).into(myUserImageView);
}
My method to create BitMap from custom view is--
public static Bitmap createDrawableFromView(Context context, View view) {
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
My code to add Marker is--
if (googleMap != null)
{
final LatLng currentAddressLatLong = new LatLng(gps.getLatitude(), gps.getLongitude());
//LatLng currentAddressLatLong = new LatLng(latitude, longitude);
Bitmap markerUserBitmap = CommonFunctions.createDrawableFromView(NearByActivity.this, myUserMarkerLayout);
googleMap.addMarker(new MarkerOptions().position(currentAddressLatLong).icon(BitmapDescriptorFactory.fromBitmap(markerUserBitmap)).anchor(0.5f, 1));
}
I checked, my code is creating expected bitmap successfully also code to add marker on google map is executing successfully, but marker is not visible on Map. Please guide me and let me know if I can provide more information for the same. Thank you.

Related

Show Marker title permanently in Google maps for android

I want to display each marker title and snippet for all the markers in Google maps without clicking the marker, i.e it should display by default for all markers, something like this is trying to achieve?
How can I show label/title for marker permanently in Google Maps V3?
according to documentation there is an way
showInfoWindow() but only displays for only one marker, how can i do this for all markers? or is there any other way to display marker information without clicking it?
For multiple markers with title write below code on onMapReady method of your activity.
Hope this helps...
for (int i = 0; i < listOfMarkers.size(); i++) {
LatLng latLng = new LatLng(listOfMarkers.get(i).latitude,listOfMarkers.get(i).longitude);
Marker mk = googlemap.addMarker(new MarkerOptions()
.position(latLng)
.icon(BitmapDescriptorFactory.fromBitmap(getMarkerBitmapFromView(listOfMarkers.get(i).getTitle());
}
}
private Bitmap getMarkerBitmapFromView(String resId) {
View customMarkerView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.map_item_textview, null);
TextView markerImageView = (TextView) customMarkerView.findViewById(R.id.tv_map_item_price);
markerImageView.setText(resId);
markerImageView.setTextColor(Color.parseColor("#000000"));
customMarkerView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
customMarkerView.layout(0, 0, customMarkerView.getMeasuredWidth(), customMarkerView.getMeasuredHeight());
customMarkerView.buildDrawingCache();
Bitmap returnedBitmap = Bitmap.createBitmap(customMarkerView.getMeasuredWidth(), customMarkerView.getMeasuredHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_IN);
Drawable drawable = customMarkerView.getBackground();
if (drawable != null)
drawable.draw(canvas);
customMarkerView.draw(canvas);
return returnedBitmap;
}

how to use xml layout as cluster marker Android

I have a question, Is it possible to set a layout with multi imageviews and textviews as a cluster marker on the google map by android map utils? and how? if somebody provide an good example it would be great this an example of what i want to do:
thanks
I don't know if there is an easier way than what I used that was a year a go this method takes a lot of time if the data set is big so use it on small data set or talk to the designer for other options.
you can create a layout with what you want the get the bitmap of this layout this add the bitmap as a marker to the map since add marker only takes images.
*you need to set the data before creating the bitmap
first step inflate and set data to your layout
View marker = ((LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.marker_layout, null);
second get the bitmap from this view
Bitmap bitmap = createDrawableFromView(
getActivity(), marker);
third add the bitmap as a marker
MarkerOptions mo = new MarkerOptions().position(
new LatLng(lat, lng))
// .title(address)
.snippet(i + "")
.icon(BitmapDescriptorFactory
.fromBitmap(bitmap));
Marker customMarker = googleMap.addMarker(mo);
this is how to get the bitmap
public static Bitmap createDrawableFromView(Context context, View view) {
DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null) {
((Activity) context).getWindowManager().getDefaultDisplay()
.getMetrics(displayMetrics);
view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
view.layout(0, 0, displayMetrics.widthPixels,
displayMetrics.heightPixels);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
return null;
}
goodluck with that it was a lot of pain.

Customising marker in android map, placing text inside image

I have an image to show as marker, inside that image i have to update time when the map is moving
The problem facing now is
I dont know how to show time inside my custom image.
BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.drawable.ic_remaining_time);
googleMap.addMarker(new MarkerOptions()
.position(cameraPosition.target)
.title(cameraPosition.toString())
.icon(descriptor)
);
Please anyone help me
Make drawable on every time when map get changed or move and set icon like below
marker.setIcon(BitmapDescriptorFactory.fromBitmap(CommonUtils.writeOnDrawable(mContext,R.drawable.ic_location,"your text here").getBitmap()));
// Bitmap Drawable method
public static BitmapDrawable writeOnDrawable(Context context, int drawableId, String text){
Bitmap bm = BitmapFactory.decodeResource(context.getResources(), drawableId).copy(Bitmap.Config.ARGB_8888, true);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setTextSize(30);
paint.setTextAlign(Paint.Align.CENTER);
Canvas canvas = new Canvas(bm);
// Change the position of text here
canvas.drawText(text,bm.getWidth()/2 //x position
, bm.getHeight()/2 // y position
, paint);
return new BitmapDrawable(context.getResources(),bm);
}
you can get the marker when u first time add marker in google map object
Marker marker = googleMap.addMarker(new MarkerOptions().position(new LatLng(mLocation.getLatitude(), mLocation.getLongitude())).title(allJob.getBusiness().getName()).icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_location_icon)));
I don't reccomend to update repeatedly a text inside an image in marker because to achieve that you must creat a bitmap with the image and text and put that bitmap as icon marker and that's not free (in terms of memory usage).
But you can try, anyway... Create the bitmap descriptor that way and put inside the icon:
public static Bitmap createDrawableFromView(Context context, View view) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
view.setLayoutParams( new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT ) );
view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap); view.draw(canvas);
return bitmap;
}
Pass to that function the view you can set as icon, inflating an xml maybe.
Try something like this -
BitmapDescriptor descriptor = BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getActivity().getResources(),R.drawable.ic_remaining_time));
googleMap.addMarker(new MarkerOptions()
.position(cameraPosition.target)
.title(cameraPosition.toString())
.icon(descriptor)
);
To get customized marker inflate your custom layout at the place of marker like below -
private Bitmap fillCustomizedMarker(int markerResource) {
//Log.d(TAG, "fillMarkerWithText ++");
View markerLayout;
markerLayout = getActivity().getLayoutInflater().inflate(R.layout.custom_marker, null);
markerLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
markerLayout.layout(0, 0, markerLayout.getMeasuredWidth(), markerLayout.getMeasuredHeight());
ImageView markerImage = (ImageView) markerLayout.findViewById(R.id.marker_image);
TextView timeText = (TextView) markerLayout.findViewById(R.id.timeText);
markerImage.setImageResource(markerResource);
markerCost.setText(time);
final Bitmap bitmap = Bitmap.createBitmap(markerLayout.getMeasuredWidth(), markerLayout.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
markerLayout.draw(canvas);
return bitmap;
}
And to update this layout i would suggest you to use handler in android. It will update your UI efficiently.

create custom marker icons on runtime using android xml

I am developing an android app in which I need to download an image from its URL, create a bitmap out of it and than display it on map as an icon. so far I have successfully completed to show bitmaps dynamically on map but I need to place my images on some background. something like this shown here How to create a custom-shaped bitmap marker with Android map API v2?
any example or suggestion would be helpful.
thanks...:)
I got the answer for my above problem
I created a bitmap from view and then placed it on marker. my xml is below
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/img_id"
android:layout_width="#dimen/custom_profile_image"
android:layout_height="#dimen/custom_profile_image"
android:contentDescription="#string/content"
android:scaleType="centerCrop" />
</RelativeLayout>
inflating above xml
View viewMarker = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.custom_marker_layout, null);
ImageView myImage = (ImageView) viewMarker.findViewById(R.id.img_id);
set Imagebitmap on imageview which you download from url on runtime
myImage.setImageBitmap(Imagebitmap);
now pass view object to the method and return the bitmap out of it. like this
Bitmap bmp=createDrawableFromView(context,viewMarker);
googleMap.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude)).title(title)
.snippet(snippet)
.icon(BitmapDescriptorFactory.fromBitmap(bmp)));
now you can use returned bitmap anywhere, thats you'll be able to make custom marker icons using xmls.
public static Bitmap createDrawableFromView(Context context, View view) {
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay()
.getMetrics(displayMetrics);
view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
view.layout(0, 0, displayMetrics.widthPixels,
displayMetrics.heightPixels);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
Its working for me. Thanks!!!
There's probably a better solution, but maybe try this:
Put the background you need into your drawable folder and load the bitmap:
Bitmap marker = getResources().getDrawable(R.drawable.marker_background);
Edit a copy of it with the Image you downloaded (only pseudo, don't know if this works like this):
int xOffset = 20;
int yOffset = 50;
int xPosition = xOffset;
int yPosition = yOffset;
int numberOfPixels = image.getHeight()*image.getWidth();
int[] pixels = new int[numberOfPixels];
image.getPixels(pixels,0,0,0,0,image.getWidth(), image.getHeight());
for (int x = 0; x<numberOfPixels;x++){
marker.setPixel(xPosition,yPosition,pixels[x]);
if((xPosition-xOffset)%image.getWidth()==0){
yPosition+=1;
xPosition=xOffset;
}else{
xPosition++;
}
}
MarkerOptions markerOptions = new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(marker));

How to show text in drawable custom marker

I'm trying to create a Custom Marker that displays text with a number equal to the example below:
Example:
But when you run the application the text is not displayed, only the red ellipse appears without a number.
My Code
InicializeMap()##
private void InicializeMap()
{
if (_googleMap == null)
{
_googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.mapMapeamento)).getMap();
LatLng pos = new LatLng(23.4555453556, 11.145315551);
MapUtils mapUtils = new MapUtils(getApplicationContext());
Bitmap bitmap = mapUtils.GetBitmapMarker();
Marker marker = _googleMap.addMarker(new MarkerOptions()
.position(pos)
.icon(BitmapDescriptorFactory.fromBitmap(bitmap)));
// check if map is created successfully or not
if (_googleMap == null)
Toast.makeText(getApplicationContext(), Mensagens.erroCriarMapa, Toast.LENGTH_SHORT).show();
}
}
My method to create the Bitmap
public Bitmap GetBitmapMarker()
{
Paint color = new Paint();
color.setTextSize(35);
color.setColor(Color.BLACK);
int px = _mContext.getResources().getDimensionPixelSize(R.dimen.map_dot_marker_size);
Bitmap mDotMarkerBitmap = Bitmap.createBitmap(px, px, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(mDotMarkerBitmap);
canvas.drawText("Hello!", 30, 40, color);
Drawable shape = _mContext.getResources().getDrawable(R.drawable.shape_marker_red);
shape.setBounds(0, 0, mDotMarkerBitmap.getWidth(), mDotMarkerBitmap.getHeight());
shape.draw(canvas);
return mDotMarkerBitmap;
}
res/drawable/shape_marker_red
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<gradient
android:angle="90"
android:endColor="#f58383"
android:startColor="#ee6464" />
<stroke
android:width="1dp"
android:color="#a13939" />
</shape>
This is what I came up with.
First, declare your marker options to add the marker on the map.
MarkerOptions options = new MarkerOptions()
.position(new LatLng(GlobalApp.getInstance().getLoginUserInfo().getLatitude(),
GlobalApp.getInstance().getLoginUserInfo().getLongitude()))
.draggable(false)
.flat(false)
.icon(BitmapDescriptorFactory.fromBitmap(createStoreMarker()));
Marker tempMarker = globalGoogleMap.addMarker(options);
Add a function to inflate a layout of your specification and you can get their reference and add whatever you want.This is the place where the magic happens.
private Bitmap createStoreMarker() {
View markerLayout = getLayoutInflater().inflate(R.layout.store_marker_layout, null);
ImageView markerImage = (ImageView) markerLayout.findViewById(R.id.marker_image);
TextView markerRating = (TextView) markerLayout.findViewById(R.id.marker_text);
markerImage.setImageResource(R.drawable.ic_home_marker);
markerRating.setText(GlobalApp.getInstance().getLoginUserInfo().getStoreName());
markerLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
markerLayout.layout(0, 0, markerLayout.getMeasuredWidth(), markerLayout.getMeasuredHeight());
final Bitmap bitmap = Bitmap.createBitmap(markerLayout.getMeasuredWidth(), markerLayout.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
markerLayout.draw(canvas);
return bitmap;
}
This is the layout
store_marker_layout.xml
I am inflating
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_store_marker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<TextView
android:id="#+id/marker_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="8dp"
android:text="dgdfgdfg"
android:textColor="#android:color/black"
android:textStyle="bold" />
<ImageView
android:id="#+id/marker_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="#drawable/ic_home_marker" />
</LinearLayout>
I got the following implementation and it worked.
The implementation was as follows:
MapActivity class
MapUtils mapUtils = new MapUtils(getApplicationContext());
Bitmap bitmap = mapUtils.GetBitmapMarker(getApplicationContext(), R.drawable.marker_blue, "1");
Marker marker = _googleMap.addMarker(new MarkerOptions()
.position(pos)
.icon(BitmapDescriptorFactory.fromBitmap(bitmap)));
MapUtils Class
public Bitmap GetBitmapMarker(Context mContext, int resourceId, String mText)
{
try
{
Resources resources = mContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if(bitmapConfig == null)
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
paint.setTextSize((int) (14 * scale));
paint.setShadowLayer(1f, 0f, 1f, Color.DKGRAY);
// draw text to the Canvas center
Rect bounds = new Rect();
paint.getTextBounds(mText, 0, mText.length(), bounds);
int x = (bitmap.getWidth() - bounds.width())/2;
int y = (bitmap.getHeight() + bounds.height())/2;
canvas.drawText(mText, x * scale, y * scale, paint);
return bitmap;
}
catch (Exception e)
{
return null;
}
}
Here you go. In this method, we're creating the BitmapDescriptor with a lap number centered into one of 3 drawables.
/**
* #param lapNbr String
* #return {#link BitmapDescriptor}
*/
private BitmapDescriptor createLapBitMap(String lapNbr) {
// Determine which of the 3 icons to start from. 1 being the thinnest, 3 being the widest.
Bitmap tmp = null;
switch (lapNbr.length()) {
case 1:
tmp = BitmapFactory.decodeResource(getResources(), R.drawable.lap_icon1);
break;
case 2:
tmp = BitmapFactory.decodeResource(getResources(), R.drawable.lap_icon2);
break;
// If a dude is recording more than 999 laps, let's just shoot him. :)
default:
tmp = BitmapFactory.decodeResource(getResources(), R.drawable.lap_icon3);
break;
}
if (tmp != null) {
Bitmap.Config config = tmp.getConfig();
if (config == null) {
config = Bitmap.Config.ARGB_8888;
}
// Resource bitmpas are immutable, so we need to convert it to a mutable one.
Bitmap bm = tmp.copy(config, true);
if (bm != null) {
// Draw text to the canvas center.
Rect bounds = new Rect();
mLapIconPaint.getTextBounds(lapNbr, 0, lapNbr.length(), bounds);
int x = (bm.getWidth() - bounds.width()) / 2;
int y = ((bm.getHeight() + bounds.height()) / 2) - 10; // bump it up just a bit
Canvas c = new Canvas(bm);
c.drawText(lapNbr, x, y, mLapIconPaint);
return BitmapDescriptorFactory.fromBitmap(bm);
}
}
// Return a default bitmap with a lap circle inside of the icon.
return BitmapDescriptorFactory.fromResource(R.drawable.lap_icon1);
}
Why are you using a Bitmap here? It looks like a drawable will get the job done, and then you could programmatically change the .setText() of each variable depending on the assignment of the marker.
For example:
<Button android:id="#+id/markerButton"
android:background="#drawable/markerDrawable"/>
Then:
markerButton.setText("1");
The solution to this is now available in the Google Maps SDK for Android Utility Library

Categories

Resources