I am using the excellent Android Maps Utility library to display on the map custom markers withs clusters. It works great and it is very easy to customize.
My problem is how to change local resources from the demo (R.drawable.image_demo) to images from a URL. I'm using Universal Image Loader to load this images on the imageView async, but the problems is that the images are not loaded on the marker that corresponds.
Anyone know about any example?
This is the code where the image is downloaded and loaded inside the DefaultClusterRender class. Thanks in advance.
#Override
protected void onBeforeClusterItemRendered(MapFoto mapFoto, MarkerOptions markerOptions) {
// Draw a single person.
// Set the info window to show their name.
// mImageView.setImageResource(R.drawable.barcelona);
// mImageView.setScaleType(ScaleType.CENTER_CROP);
Log.d("", "--- url: " + mapFoto.getPictureUrl());
ImageLoader.getInstance().displayImage(mapFoto.getPictureUrl(), mImageView, BlipointApp.optionsAvatarImage, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
mImageView.setImageBitmap(loadedImage);
mImageView.setScaleType(ScaleType.CENTER_CROP);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
}
});
Bitmap icon = mIconGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon)).title(mapFoto.getName());
}
I had a similar problem using the UIL, not all images were loaded. Every time I ran the map activity and zoomed into the clusters there were different markers/clusters that had no image. Only the standard marker/cluster icons were shown.
Finally after two days of trying and trying it works fine. Temporarily I had switched to the Picasso library to see if it might work but I experienced similar problems there and couldn't get it done. Besides with Picasso all the images loaded from the web (URL) were rotated by 90 degrees. I couldn't figure out why. According to some posts that I found in the web it might have to do something with the device, I am using Samsung Galaxy S5 device for testing. But not sure....
Here some notes how I did it: I created a HardRefSimpleImageLoadingListener with an ImageView which will exist until UIL loading process is finished. Without its hard reference ImageView the onLoadingCancelled would get called and loading would not complete. I also created the objects ClusterMarkerTarget and ClusterItemMarkerTarget which contain a Marker, ImageView, and bitmap for the Icon generators. I also put them into HashSets myClusterItemMarkerTargets and myClusterMarkerTargets to keep them from getting garbagecollected.
Maybe it can be of use for somebody.
Here some code:
#Override
protected void onClusterItemRendered(ReportItem clusterItem, Marker marker) {
final ClusterItemMarkerTarget pm_ClusterItem = new ClusterItemMarkerTarget(marker);
myClusterItemMarkerTargets.add(pm_ClusterItem);
HardRefSimpleImageLoadingListener loadingListener = new HardRefSimpleImageLoadingListener() {
#Override
public void onLoadingFailed(String s, View view, FailReason failReason) {
myClusterItemMarkerTargets.remove(pm_ClusterItem);
}
#Override
public void onLoadingComplete(String s, View view, Bitmap bitmap) {
mClusterItemImageView.setImageBitmap(bitmap);
pm_ClusterItem.myIcon_cluster = mClusterItemIconGenerator.makeIcon();
pm_ClusterItem.mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(pm_ClusterItem.myIcon_cluster));
myClusterItemMarkerTargets.remove(pm_ClusterItem);
}
#Override
public void onLoadingCancelled(String s, View view) {
myClusterItemMarkerTargets.remove(pm_ClusterItem);
}
};
ImageLoader.getInstance().displayImage(clusterItem.picPath, pm_ClusterItem.myClusterItemImageView , loadingListener );
}
#Override
protected void onClusterRendered(Cluster<ReportItem> cluster, Marker marker) {
int i=0;
clustersize = cluster.getSize();
final ClusterMarkerTarget pm_Cluster = new ClusterMarkerTarget(marker, cluster);
myClusterMarkerTargets.add(pm_Cluster);
for (ReportItem r : cluster.getItems()) {
// Draw 1 at most.
if (i == 1 ) {
break;
}
HardRefSimpleImageLoadingListener loadingListener = new HardRefSimpleImageLoadingListener() {
#Override
public void onLoadingFailed(String s, View view, FailReason failReason) {
myClusterMarkerTargets.remove(pm_Cluster);
}
#Override
public void onLoadingComplete(String s, View view, Bitmap bitmap) {
mClusterImageView.setImageBitmap(bitmap); // = (ImageView) view; //pm.myClusterImageView;
pm_Cluster.myIcon_clusterItem = mClusterIconGenerator.makeIcon(String.valueOf(clustersize));
pm_Cluster.myMarker.setIcon(BitmapDescriptorFactory.fromBitmap(pm_Cluster.myIcon_clusterItem));
myClusterMarkerTargets.remove(pm_Cluster);
}
#Override
public void onLoadingCancelled(String s, View view) {
myClusterMarkerTargets.remove(pm_Cluster);
}
};
ImageLoader.getInstance().displayImage(r.picPath, pm_Cluster.myClusterImageView, loadingListener);
i++;
}
}
more:
//Set for holding a reference to marker targets --> targets won't get carbage collected during looping and loading images
Set<ReportRenderer.ClusterItemMarkerTarget> myClusterItemMarkerTargets = new HashSet<>();
Set<ReportRenderer.ClusterMarkerTarget> myClusterMarkerTargets = new HashSet<>();
more:
public ReportRenderer(ClusterManager<ReportItem> mClusterManager, GoogleMap map) {
super(MyApplication.getContext(), map, mClusterManager);
mDimension = (int) MyApplication.getContext().getResources().getDimension(R.dimen.custom_report_image);
mPadding = (int) MyApplication.getContext().getResources().getDimension(R.dimen.custom_report_padding);
// initialize cluster icon generator
View multiReport = inflater.inflate(R.layout.multi_report, null);
mClusterImageView = (ImageView) multiReport.findViewById(R.id.image_report);
mClusterIconGenerator = new IconGenerator(MyApplication.getContext());
mClusterIconGenerator.setContentView(multiReport);
// initialize cluster item icon generator
mClusterItemImageView = new ImageView(MyApplication.getContext());
mClusterItemImageView.setLayoutParams(new ViewGroup.LayoutParams(mDimension, mDimension));
mClusterItemImageView.setPadding(mPadding, mPadding, mPadding, mPadding);
mClusterItemIconGenerator = new IconGenerator(MyApplication.getContext());
mClusterItemIconGenerator.setContentView(mClusterItemImageView);
// initialize image loader
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.loading)
.showImageForEmptyUri(R.drawable.warning)
.showImageOnFail(R.drawable.fail)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
//.bitmapConfig(Bitmap.Config.RGB_565)
.build();
config = new ImageLoaderConfiguration.Builder(MyApplication.getContext())
.defaultDisplayImageOptions(options)
.build();
ImageLoader.getInstance().init(config);
}
more:
//cluster marker with image loaded by Ultimate Image Loader
class ClusterMarkerTarget {
Marker myMarker;
ImageView myClusterImageView;
public ClusterMarkerTarget(Marker marker, Cluster<ReportItem> cluster) {
myMarker = marker;
View multiReport = inflater.inflate(R.layout.multi_report, null);
myClusterImageView = (ImageView) multiReport.findViewById(R.id.image_report);
}
}
//cluster item marker with image loaded by Ultimate Image Loader
class ClusterItemMarkerTarget {
Marker mMarker;
ImageView myClusterItemImageView;
public ClusterItemMarkerTarget(Marker marker) {
mMarker = marker;
myClusterItemImageView = new ImageView(MyApplication.getContext());//mClusterItemImageView;
myClusterItemImageView.setLayoutParams(new ViewGroup.LayoutParams(mDimension, mDimension));
int padding = (int) MyApplication.getContext().getResources().getDimension(R.dimen.custom_report_padding);
myClusterItemImageView.setPadding(padding, padding, padding, padding);
}
}
and finally:
class HardRefSimpleImageLoadingListener extends SimpleImageLoadingListener {
public ImageView mView;
#Override
public void onLoadingStarted(String imageUri, View view) {
mView = (ImageView) view;
}
}
Related
I am trying to display images from url addresses in a RecyclerView ImageView, But only [this url][1] and [this url][2] image is being displayed. When I change url to other image urls, no images is diplaying, but only white background in the shape of the image comes out.
#Override
public void onBindViewHolder(CategoryGridAdapter.ViewHolder holder, final int position) {
final CategoryGridModel categoryGridModel = categoryGridModels.get(position);
holder.textView.setText(categoryGridModel.getDescription ());
holder.frameLayout.setBackgroundColor (Color.parseColor (categoryGridModel.getColor ()));
Glide.with(holder.imageView)
//.load("https://www.sarahmcculloch.com/wp-content/uploads/2015/06/flat-duolingo.png") //Image not showing with this URL
.load("https://lh6.ggpht.com/9SZhHdv4URtBzRmXpnWxZcYhkgTQurFuuQ8OR7WZ3R7fyTmha77dYkVvcuqMu3DLvMQ=w300") //Image showing properly
.apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.RESOURCE)
.error(R.drawable.ic_icon_volleyball))
.into(holder.imageView);
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, categoryGridModel.getImageUrl (), Toast.LENGTH_SHORT).show();
}
});
}
Hi guys I'm a beginner with Android programming and I'm trying to make custom InfoWindow for my markers on my map application. My InfoWindows have to display a dynamical image (I download and set with Picasso library) different markers ad hoc and some text fields, like the name of the "POI", the address and the distance in minutes, walking and with a car. The problem is that InfoWindowAdapter are images and so I've seen that the only way is to force reload the showing of the marker's infowindow. But if I try (as I seen on some forums and also in others questions here on StackOverflow), my app crash. Below I post my code with comment that can help you and the screen of my app. Really thanks all of you.
Screenshot:
Code:
// ****** Custom InfoWindowAdapter ****** //
map.setInfoWindowAdapter(new InfoWindowAdapter() {
View v = getLayoutInflater().inflate(R.layout.custom_info_window, null);
#Override
public View getInfoWindow(Marker marker) { //As I've seen on the web, if the marker is null and it is showing infowindow, I do a refresh,
if (marker != null && marker.isInfoWindowShown()){ //but with the debug I've seen that it doesn't never enter in this IF statement and nothing happen when the image is loaded.
marker.hideInfoWindow();
marker.showInfoWindow();
}
return null;
}
#Override
public View getInfoContents(final Marker marker) {
BuildInfoMatrix req = new BuildInfoMatrix();
String nome = marker.getTitle();
String currentUrl = "";
int vuoto = -15;
try{
currentUrl=req.findImageUrl(nome); //from another class (BuildInfoMatrix) I retrieve the right image marker URL to display
}catch(Exception e){
currentUrl = "http://upload.wikimedia.org/wikipedia/commons/b/bb/XScreenSaver_simulating_Windows_9x_BSOD.png"; //If the currentURL is null (I haven't set any URL for the marker) it set an error image
}
if (currentUrl == null)
{
currentUrl = "http://upload.wikimedia.org/wikipedia/commons/b/bb/XScreenSaver_simulating_Windows_9x_BSOD.png";
}
ImageView image;
image = (ImageView) v.findViewById(R.id.image_nuvoletta); //image_nuvoletta is where it will be placed on the InfoWindowAdapter
Picasso.with(v.getContext()) //Here with Picasso I download the image and I set into
.load(currentUrl) //R.id.image_nuvoletta
.error(R.drawable.ic_launcher)
.resize(150, 110)
.into(image, new Callback(){
#Override
public void onSuccess(){
//I should reload here (when the image have been downloaded) the infoWindowAdapter but
//if I place here "marker.showInfoWindow()" the app crash; without, nothing happens.
}
#Override
public void onError(){
}
});
/***********************************/
I have the same problem, after going to anywhere and no answer found, i do try my self with new Handler().postDelayed() and it's really work for me.
#Override
public View getInfoWindow(Marker marker) {
// Left it empty
return null;
}
#Override
public View getInfoContents(final Marker marker) {
....
Picasso.with(v.getContext()) //Here with Picasso I download the image and I set into
.load(currentUrl) //R.id.image_nuvoletta
.error(R.drawable.ic_launcher)
.resize(150, 110)
.into(image, new Callback(){
#Override
public void onSuccess(){
new Handler().postDelayed(new Runnable() {
public void run() {
marker.showInfoWindow();
}
}, 500);
}
#Override
public void onError(){
new Handler().postDelayed(new Runnable() {
public void run() {
marker.showInfoWindow();
}
}, 500);
}
});
}
Don't forget to vote if this snippet work for you.
I am loading ImageView using the below code from URL
int resID = getResources().getIdentifier(name, "drawable", this.getPackageName());
chat_home.setImageResource(resID);
while I refresh the page, ImageView (i.e chat_home) is disappear for several second during that time I have to discard the chat_home.setOnClickListener. Once the ImageView is displayed in the screen, then I want to enable the chat_home.setOnClickListener.
chat_home.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if(checkInternetConnection())
{
Intent intent = new Intent(ActivityOne.this, ActivityTwo.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
//intent.putExtra(MainActivity.check, result);
startActivity(intent);
}
else
{
// my toast
}
});
So my question is how to check whether the imageview is filled or empty in the screen.
I'm guessing the "loading" part is when you're calling
chat_home.setImageResource(resID);
Just create a flag that is false until this method executes (so set it to true immediately after this statement).
Then, in your onClickListener,
#Override
public void onClick(View v) {
if(flag) {
// execute code
} else {
// do nothing
}
}
Use Universal image loader. in that there is several methods are as under.
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view
// which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView, displayOptions, new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
...
//here you can set
view.setEnable(false)
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
...
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
//here you can set
view.setEnable(true);
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
...
}
}, new ImageLoadingProgressListener() {
#Override
public void onProgressUpdate(String imageUri, View view, int current, int total) {
...
}
});
For loading image you need use one of the method.
String imageUri = "assets://image.png"; // from assets
String imageUri = "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)
Note:
To use universal image loader library you have to configure first.for that all instruction given in below link.
Universal-image-loader
I'm doing some research on Universal Image Loader library and I found It awsome. But I have a doubt. I want to download an image from an URL, catch It into SD/Internal memory and use It into a Linear Layout Background. As far as I undestand AIL it catch images when you use the displayImage(..) methods. Does anyone know If It's possible to download an Image from URL, catch It and load It into a Bitmap to use It later into Layouts' backgrounds? I can accept any other solution to acomplish that. Thanks
EDIT
Just to be clear what I wanna do is
1.- Download an Image
2.- catch It
3.-load It as Bitmap so I can do something like that
Bitmap b=(image catched by UIL);
BitmapDrawable drawableBitmap=new BitmapDrawable(b);
linearLayout.setBackgroundDrawable(drawableBitmap);
you can use the below code to set downloaded image in layout.
ImageLoader.getInstance().loadImage(pack.getCoverImageUrl(), new SimpleImageLoadingListener(){
#Override
public void onLoadingStarted(String imageUri, View view) {
super.onLoadingStarted(imageUri, view);
}
#Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
super.onLoadingFailed(imageUri, view, failReason);
}
#Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
rl_header_main.setBackgroundDrawable(new BitmapDrawable(loadedImage));
rl_header_main.setAlpha();
}
#Override
public void onLoadingCancelled(String imageUri, View view) {
super.onLoadingCancelled(imageUri, view);
}
});
Enjoy :)
I want to show an InfoWindow on markers in a Maps V2 fragment.
Thing is, I want to show BitMaps that are dynamically loaded from the web with Universal Image Downloader.
This is my InfoWindowAdapter:
class MyInfoWindowAdapter implements InfoWindowAdapter {
private final View v;
MyInfoWindowAdapter() {
v = getLayoutInflater().inflate(R.layout.infowindow_map,
null);
}
#Override
public View getInfoContents(Marker marker) {
Item i = items.get(marker.getId());
TextView tv1 = (TextView) v.findViewById(R.id.textView1);
ImageView iv = (ImageView) v.findViewById(R.id.imageView1);
tv1.setText(i.getTitle());
DisplayImageOptions options = new DisplayImageOptions.Builder()
.delayBeforeLoading(5000).build();
imageLoader.getMemoryCache();
imageLoader.displayImage(i.getThumbnailUrl(), iv, options,
new ImageLoadingListener() {
#Override
public void onLoadingStarted(String imageUri, View view) {
// TODO Auto-generated method stub
}
#Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
// TODO Auto-generated method stub
}
#Override
public void onLoadingComplete(String imageUri,
View view, Bitmap loadedImage) {
Log.d("MAP", "Image loaded " + imageUri);
}
#Override
public void onLoadingCancelled(String imageUri,
View view) {
// TODO Auto-generated method stub
}
});
return v;
}
#Override
public View getInfoWindow(Marker marker) {
// TODO Auto-generated method stub
return null;
}
}
I have 2 problems with this:
As we know the InfoWindow is drawn and later changes to it (in my case the new BitMap on the ImageView) are not shown/ the InfoWindow is not being updated. How can I "notify" the InfoWindow to reload itself when the imageLoader has finished? When I put
marker.showInfoWindow()
into onLoadingComplete it created an infinite loop where the marker will pop up, start loading the image, pop itself up etc.
My second problem is that on a slow network connection (simulated with the 5000ms delay in the code), the ImageView in the InfoWindow will always display the last loaded image, no matter if that image belongs to that ImageWindow/ Marker.
Any suggestions on how to propperly implement this?
You should be doing Marker.showInfoWindow() on marker that is currently showing info window when you receive model update.
So you need to do 3 things:
create model and not put all the downloading into InfoWindowAdapter
save reference to Marker (call it markerShowingInfoWindow)
from getInfoContents(Marker marker)
when model notifies you of download complete call
if (markerShowingInfoWindow != null && markerShowingInfoWindow.isInfoWindowShown()) {
markerShowingInfoWindow.showInfoWindow();
}
I did something similar.
This was still giving me the recession error
if (markerShowingInfoWindow != null && markerShowingInfoWindow.isShowingInfoWindow()) {
markerShowingInfoWindow.showInfoWindow();
}
So what i did was simply closes the window and open it again
if (markerShowingInfoWindow != null && markerShowingInfoWindow.isShowingInfoWindow()) {
markerShowingInfoWindow.hideInfoWindow();
markerShowingInfoWindow.showInfoWindow();
}
for a better detail version of the same answer here is my original soultion LINK
I was also faced same situation and solved using the following code.
In my adapter I have added public variable
public class MarkerInfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
public String ShopName="";
-------
-------
#Override
public View getInfoWindow(Marker arg0) {
View v;
v = mInflater.inflate(R.layout.info_window, null);
TextView shop= (TextView) v.findViewById(R.id.tv_shop);
shop.setText(ShopName);
}
}
and added MarkerClickListener in my main activity
----
MarkerInfoWindowAdapter mMarkerInfoWindowAdapter;
----
----
#Override
public void onMapReady(GoogleMap googleMap) {
mMarkerInfoWindowAdapter = new MarkerInfoWindowAdapter(getApplicationContext());
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(final Marker arg0) {
mMarkerInfoWindowAdapter.ShopName= "my dynamic text";
arg0.showInfoWindow();
return true;
}
}
mMap.setInfoWindowAdapter(mMarkerInfoWindowAdapter);
}
I've used the code in this article, and it worked well.
http://androidfreakers.blogspot.de/2013/08/display-custom-info-window-with.html