So I'm using a ClusterManagerto cluster my Markers, so that the user can have a better experience.
I have actually implemente Google's code, which I found here. Imagine now that my Marker icon is a ball. I want the background of the icon to be transparent, not white.
On Google's original tutorial they set a ImageView to the IconGenerator, like this:
public class MyClusterManagerRenderer extends DefaultClusterRenderer<ClusteredMarker> {
private final IconGenerator mIconGenerator;
private final ImageView mImageView;
public MyClusterManagerRenderer(Context context, GoogleMap googleMap,
ClusterManager<ClusteredMarker> clusterManager){
super(context, googleMap, clusterManager);
mIconGenerator = new IconGenerator(context);
mImageView = new ImageView(context);
mIconGenerator.setContentView(mImageView);
}
#Override
protected void onBeforeClusterItemRendered(ClusteredMarker item, MarkerOptions markerOptions) {
mImageView.setImageResource(item.iconPicture);
Bitmap icon = mIconGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)).title(item.user);
}
...
}
I have tried several ways to make my icon transparent, like calling:
mImageView.setBackgroundColor(Color.TRANSPARENT);
but without success. The only way I managed to find a solution is to directly attach my transparent image to the IconGenerator, like this:
mIconGenerator.setBackground(aContext.getResources().getDrawable(R.drawable.ball));
The downside of this approach is that a ImageView have some interesting methods that I would like to call, like setPadding, while the IconGenerator doesn't have that.
So, is there a way to make my icon transparent, using the ImageView?
Thank you,
The solution I found is this:
private static final Drawable TRANSPARENT_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);
// Make the background of marker transparent
mIconGenerator.setBackground(TRANSPARENT_DRAWABLE);
mImageView.setBackgroundColor(null);
That will remove the background and make it transparent. :)
Related
I need some help to improve the performance of my algorithm, I'm struggling for days and can't find a good solution.
Goal: My app need to show a marker for each airport in the world (~1k markers), and each marker must show the airport name.
What I did: For the marker, I created an RelativeLayout with the Icon and a TextView to populate the name of aiport.
Also, I wrote a class "AirportCluster" extending DefaultClusterRenderer and inside the overrode method onBeforeClusterItemRendered I just cast the layout to Bitmap so it can be rendered on the map
#Override
protected void onBeforeClusterItemRendered(AirportItem airportItem, MarkerOptions markerOptions) {
RelativeLayout customLayoutMarker = (RelativeLayout) activity.getLayoutInflater().inflate(R.layout.custom_airport_marker,null);
String tAirportName = airportItem.getAirport().getAirportName().toLowerCase();
tAirportName = Character.toUpperCase(tAirportName.charAt(0)) + tAirportName.substring(1);
TextView textLabelAirportMarker = (TextView) customLayoutMarker.findViewById(R.id.label_text_airport_marker);
textLabelAirportMarker.setText(tAirportName);
customLayoutMarker.setDrawingCacheEnabled(true);
customLayoutMarker.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
customLayoutMarker.layout(0,0, customLayoutMarker.getMeasuredWidth(), customLayoutMarker.getMeasuredHeight());
customLayoutMarker.buildDrawingCache(true);
Bitmap flagBitmap;
if ( mMemoryCache.get(tAirportName) == null){
flagBitmap = Bitmap.createBitmap(customLayoutMarker.getDrawingCache());
mMemoryCache.put(tAirportName,flagBitmap);
}else{
flagBitmap = mMemoryCache.get(tAirportName);
}
BitmapDescriptor markerAirportWithText = BitmapDescriptorFactory.fromBitmap(flagBitmap);
markerOptions.icon(markerAirportWithText);
//markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.airport_marker));
}
As we can see in the code, I'm trying to cache it on the memory as well, but this is not working that good.
All the markers are being added on the method onMapReady inside a loop for each airport in the list
for (Airport temp : fixedAirports) {
LatLng latLng = new LatLng(temp.getCityLat(), temp.getCityLng());
// create marker
MarkerOptions markerOptions = new MarkerOptions().position(latLng).title("Marker in" + temp.getCityName());
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.airport_marker));
AirportItem offsetItem = new AirportItem(temp.getCityLat(), temp.getCityLng());
offsetItem.setAirport(temp);
mClusterManager.addItem(offsetItem);
}
Issue: I also have a custom image for clustered airports, and when i try to zoom in/out sometimes it take to much to the clustered icon dismiss and show the marker item for an airport, sometimes the icon of the item even overlaps the clustered one, just like on the images below.
What I have to do to these animations (changing from clustered icon from single markers) be more fast and smooth??
Prepare BitmapDescriptors first in background (i.e. Coroutines viewModelScope or another thread or asynctask or Rxjava), then load them to ui. Dont draw anything inside your ClusterRenderer class. Doing so helped me a bit.
I am really struggling with google map util these days challenge after challenge and there is not good example or solution on the net.
This is my code:
#Override
protected void onBeforeClusterRendered(Cluster<ItemCluster> cluster,
MarkerOptions markerOptions) {
View marker = (getActivity()
.getLayoutInflater())
.inflate(R.layout.info_windows, null);
Bitmap bitmap = createDrawableFromView(
getActivity(), marker);
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
}
The problem is before I send the view to this function to make a bitmap for marker, I try to set some data in my info_windows.xml which is included with some ImageViews and TextViews. But the app hangs, do you have any idea how to make this done?
Bitmap bitmap = createDrawableFromView(
getActivity(), marker);
I solve my problem by making an IconGenerator objectand then make the view from that this is how i did it:
first i made the object:
private final IconGenerator mClusterIconGenerator = new IconGenerator(getActivity().getApplicationContext());
and a view which contains our XML view file of our costum marker:
View markerIcon = getActivity().getLayoutInflater().inflate(R.layout.marker_icon, null);
then set the view on icongenerator:
mMarkerIconGenerator.setContentView(markerIcon);
then you need to initiate your imageview, textview, ... then set the values that you want to show inside your costum marker like this for ex:
mMarkerViento = (ImageView) clusterIcon.findViewById(R.id.viento);
then inside the ovveride method of:
#Override
protected void onBeforeClusterItemRendered(ItemCluster item, MarkerOptions markerOptions)
mMarkerViento.setImageResource(R.drawable.viento_ne2);
and at the end you generate your bitmap object from icon generator like this:
mMarkerIconGenerator.setBackground(TRANSPARENT_DRAWABLE); // set the background as transparent
Bitmap bitmap = mMarkerIconGenerator.makeIcon(); // make a bitmap object from the icon object
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap)); // set the bitmap as marker icon
good luck and tanx
From my understanding, the ImageButton within LibGDX is a frame containing an image. Is it possible to set the background of the frame?
For example, I would like to use a Button background, and apply an Icon on top of that image.
Current Code
Skin with the background:
"com.badlogic.gdx.scenes.scene2d.ui.ImageButton$ImageButtonStyle": {
"default": {
"imageDown": "button-down",
"imageUp": "button-up"
}
}
Creating the ImageButton:
// Getting imageButtonStyle with "default" style, as it just has the background.
ImageButton.ImageButtonStyle imageButtonStyle = skin.get( "default", ImageButton.ImageButtonStyle.class );
ImageButton button = new ImageButton( imageButtonStyle );
// Set the image on the button to something.
Background image.
Background image with icon overlayed.
Thank you for your help.
The trick is using the 2 different Styles available. ImageButtonStyle to set the icon attributes, but since ImageButtonStyle extends ButtonStyle, the background attributes are set in ButtonStyle. Something like:
ImageButtonStyle style = new ImageButtonStyle();
style.up = background;
style.down = background;
style.checked = background;
style.imageUp = icon_up;
style.imageDown = icon_down;
style.imageChecked = icon_checked;
style.unpressedOffsetY = -20; // to "not" center the icon
style.unpressedOffsetX = -30; // to "not" center the icon
ImageButton heartButton = new ImageButton(style);
ImageButton envelopeButton = new ImageButton(envelopeStyle);
Something like that (for me, backround, icon_* are Drawable). But that's the basics and worked like a charm for me.
You could implement your own button class that extends ImageButton.
Then, if you overload the constructor, you can pass either Drawables or Textures for imageUp, imageDown and background to it:
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.SpriteDrawable;
public class myButton extends ImageButton
{
public myButton(Texture texture_up, Texture texture_down, Texture background)
{
super(new SpriteDrawable(new Sprite(texture_up)),
new SpriteDrawable(new Sprite(texture_down)));
this.setBackground(new SpriteDrawable(new Sprite(background));
}
}
Now, you can use your own Button class and instantiate it as follows:
Texture textureUp = new Texture(Gdx.files.internal("data/image_up.png"));
Texture textureDown = new Texture(Gdx.files.internal("data/image_down.png"));
Texture background = new Texture(Gdx.files.internal("data/background.png"));
MyButton myButton = new MyButton(textureUp, textureDown, background);
Maybe play around with it a little and you'll find out what else you can do with it. Just make sure that you have the images in the correct resolution. Background doesn't have to be an image.
A button by definition will have three states:
imageDown - When the mouse is clicked on the button
imageUp - When the mouse is released on the button
imageChecked - When the mouse is hovering on the button
In the scene2d api there isn't a way yet of manually setting the imageButton's background image but if you do want something like that its best to have an array of images and an index as to what image you want, and render using a sprite batch e.g:
Texture[] images;
int currentImage;
I'm using an ItemizedOverlay containing a list of OverlayItems to display markers on top of a MapView. My problem is that when an OverlayItem uses the default marker defined for the overlay, its getMarker() method returns null. Is there another way I can get that marker image? I'd like to see if I can animate it during onTap().
I'm showing a bunch of markers on the map, many of which use the same image, so I thought it best to make use of the overlay's default image to save memory. For this app it's possible there could be more than 100 markers displayed for a given overlay.
You have a couple of different ways how to address this. I'm showing the simplest one I know, if it don't solves your problem, let me know.
public class MyItemizedNewOverlay extends ItemizedOverlay<OverlayNewItem> {
private ArrayList<OverlayNewItem> myOverlays ;
Drawable defaultMarker;
Context context;
public MyItemizedNewOverlay(Drawable defaultMarker, Context context) {
super(boundCenterBottom(defaultMarker));
this.defaultMarker = defaultMarker;
this.context = context;
myOverlays = new ArrayList<OverlayNewItem>();
populate();
}
. . .
}
With this you can use the default marker in your code for the onTap()
I'm working on a map in Android, with several overlay icons covering it. My problem is that each overlay's icon is static and does not resize with the rest of the map when zooming in and out. This can become awkward if the user zooms too far in or out and the icons appear too big or too small.
My solution is to create multiple image files with different sizes of each icon. However, I'm not sure how to reference these icons from my (extended) MapView class after I've already created them from my :
public class Map extends MapActivity {
...
public onCreate() {
...
//Very simplified copy of my working code:
Drawable defaultDrawable = this.getResources().getDrawable(R.drawable.myicon);
List<Overlay> mapOverlays = mapView.getOverlays();
ItemizedOverlay overlayManager = new OverlayManager(defaultDrawable, this);
OverlayItem myOverlay = new OverlayItem(...);
overlayManager.addOverlay(myOverlay);
}
}
I extended the MapView class so that I could trigger zoom events. The dispatchDraw() method is where I plan to place my icon-replacement code, but I'm not sure how I can access the map's existing overlays and their icons from here (and change just their icons):
public class ZoomSensitiveMapView extends MapView {
private int oldZoomLevel;
...
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (getZoomLevel() != oldZoomLevel) {
if (getZoomLevel() > 15) {
//Zoomed in closer
//Replace icons with bigger copies
}
else {
//Zoomed out further
//Replace icons with smaller copies
}
oldZoomLevel = getZoomLevel();
}
}
}
I was thinking getOverlays() might work here, but that seems to only return the overlays themselves, not their icons.
Am I on the right track? How can I replace the icons without adjusting their overlay coordinates, etc.? Any help or recommendations would be greatly appreciated here! (Hopefully my explanation is clear enough; if anything is not, please ask me to clarify!) Thanks in advance for your help!
here you can change with line ::
Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
just put your own icon in drawable folder and update with
Drawable drawable = this.getResources().getDrawable(R.drawable.yourIcon);
For more information :: get from here