I use Glide to load my image. I need to modify my image with a SimpleTarget callback, however when the image loaded to my list, and I scroll the list shows first always an other image, and than animate the right image after 1 second to the place. Without image modification and SimpleTarget everything works just fine. Here is my code.
#BindingAdapter("imageSrc")
public static void setImage(ImageView imageView, String url) {
Glide.with(imageView.getContext()).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation anim) {
//the bitmap modified here
imageView.setImageBitmap(bmp);
}
});
}
is there any solution to avoid the flickering?
I'm trying to layout a custom infoWindow programmatically. I want to load a streetView preview image using Picasso but the image isn't showing up, any idea why?
private View prepareInfoView(Marker marker){
//prepare InfoView programmatically
LinearLayout infoView = new LinearLayout(EarthquakeActivity.this);
LinearLayout.LayoutParams infoViewParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
infoView.setOrientation(LinearLayout.VERTICAL);
// attach the above layout to the infoView
infoView.setLayoutParams(infoViewParams);
//create street view preview # top
ImageView streetViewPreviewIV = new ImageView(EarthquakeActivity.this);
// this scales the image to match parents WIDTH?, but retain image's height??
LinearLayout.LayoutParams streetViewImageViewParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
streetViewPreviewIV.setLayoutParams(streetViewImageViewParams);
String imageURL = "https://maps.googleapis.com/maps/api/streetview?size=200x200&location=";
String markerLongitude = Double.toString(marker.getPosition().longitude);
String markerLatitude = Double.toString(marker.getPosition().latitude);
imageURL += markerLatitude + "," + markerLongitude + "&fov=120&heading=0&pitch=0";
Log.wtf("prepareInfoView", imageURL);
Picasso.with(this).load(imageURL).into(streetViewPreviewIV);
infoView.addView(streetViewPreviewIV);
I've tried with and without the api key appending the url.
It did work for a few clicks without the key, but hasn't since, with or without. Is the because it's too slow fetching it so Android gives up and loads the info window without it? Is there a best in class way to do this?
Would another image loading library work better? Google's volley?
Also with
LinearLayout.LayoutParams
I'd like the image to stretch across the width of the info windows, i.e. match_parent, and to scale vertically to maintain original aspect ratio, how do I do this?
This is my answer
In commonsWare new class I add this flag:
#Override
public void onSuccess() {
Log.i(TAG, "image got, should rebuild window");
if (marker != null && marker.isInfoWindowShown()) {
Log.i(TAG, "conditions met, redrawing window");
marker.setTag(new Boolean("True"));
marker.showInfoWindow();
}
}
And in prepareInfoView, I test for the flags absence.
if (marker.getTag() == null ) {
Log.i("prepareInfoView", "fetching image");
Picasso.with(this).load(imageURL).fetch(new MarkerCallback(marker));
}
else {
Log.wtf("prepareInfoView", "building info window");
Party on! :)
Is the because it's too slow fetching it so Android gives up and loads the info window without it?
Picasso loads asynchronously unless the image is cached. And the way Maps V2 works is that the View you return is converted into a Bitmap, and that is what gets rendered. As a result, you have a race condition between Picasso and Maps V2 (does the image get loaded before the Bitmap gets created?), and so it is indeterminate as to whether or not any given info window will work.
You can call showInfoWindow() on the Marker after Picasso has loaded the image, so you can populate the ImageView from Picasso's cache. showInfoWindow(), called on a Marker, triggers Maps V2 to regenerate the info window.
For example, you could change your existing into() call into into(streetViewPreviewIV, new MarkerCallback(marker)), with a MarkerCallback like:
static class MarkerCallback implements Callback {
Marker marker=null;
MarkerCallback(Marker marker) {
this.marker=marker;
}
#Override
public void onError() {
Log.e(getClass().getSimpleName(), "Error loading thumbnail!");
}
#Override
public void onSuccess() {
if (marker != null && marker.isInfoWindowShown()) {
marker.showInfoWindow();
}
}
}
Would another image loading library work better? Google's volley?
They will all suffer from the same issue.
What is working for me is this:
public class MarkerCallback implements Callback {
Marker marker=null;
String URL;
ImageView userPhoto;
MarkerCallback(Marker marker, String URL, ImageView userPhoto) {
this.marker=marker;
this.URL = URL;
this.userPhoto = userPhoto;
}
#Override
public void onError() {
//Log.e(getClass().getSimpleName(), "Error loading thumbnail!");
}
#Override
public void onSuccess() {
if (marker != null && marker.isInfoWindowShown()) {
marker.hideInfoWindow();
Picasso.with(getActivity())
.load(URL)
.into(userPhoto);
marker.showInfoWindow();
}
}
}
All I figured out is,
Picasso loads image asynchronously, so when a marker shows it's info window after clicking by internally calling the method getInfoContents or getInfoWindow method ,
by this time if the image isn't already downloaded or cached by Picasso , then it is not showed on infoWindow.
Picasso tries to load the image into imageview of infoWindow when downloaded, but According to Google maps V2, the infoWindows Once loaded, can't be manipulated, so image is not shown updated on the UI.
But the infowindow view was updated actually but couldn't show for the restriction, so if you just hide and show the infowindow , it is kind of refreshed, and the images are shown on updated infoWindow. you can do this in the following way,
You need to keep the marker reference, you can keep this as Activity/Fragment's member variable.
Picasso.with(context)
.load(marker.getSnippet())
.placeholder(R.drawable.ic_placeholder)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
if (currentClickedMarker != null && currentClickedMarker.isInfoWindowShown()) {
//toggle the marker's infoWindow
currentClickedMarker.hideInfoWindow();
currentClickedMarker.showInfoWindow();
}
}
#Override
public void onError() {
}
});
I struggled with this as well, here is a solution with glide inspired from the accepted answer.
This solution did not work for me without resizing the picture to a proper size. With override() (and centerCrop) it did the trick.
Keep track of the latest picture shown
private String previousImageUrl = null;
And use it to see if you need refreshing of the current image
googleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(final Marker marker) {
View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_map_info_window, null);
MyObject myObject = (MyObject) marker.getTag();
final String url = myObject.getImageUrl();
final ImageView imageView = (ImageView) view.findViewById(R.id.image_view);
GlideApp.with(getContext()).load(url)
.override(imageWidth, imageHeight) // made the difference
.centerCrop()
.into(new SimpleTarget<Drawable>() {
#Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
imageView.setImageDrawable(resource);
if (!TextUtils.equals(url, previousImageUrl)) {
previousImageUrl = url;
marker.showInfoWindow();
}
}
});
return view;
}
});
If you are using the accepted answer to fix the problem and it still doesn't work,
you're probably using .fit() .
in other words you should remove .fit() from your Picasso code.
It took me a couple hours to realize it.
I'm using picasso library for loading images from server into my application. my problem is when image loaded it has a triangle in top-left corner of image with color(like blue,green,red).
this is my code for loading image:
public static void loadDynamicImage(final String url, final Context context, final ImageView imageView, final int width, final int height){
Picasso.with(context).load(url)
.networkPolicy(NetworkPolicy.OFFLINE)
.resize(width,height)
.onlyScaleDown()
.into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(context).load(url).resize(width,height).onlyScaleDown().into(imageView);
}
});
}
the image shown is :
You have enabled debug indicators on your Picasso instance (see official website). Look for setIndicatorsEnabled(true) in your code and remove it.
You have setIndicatorsEnabled set to true
Picasso picasso = Picasso.with(this);
picasso.setIndicatorsEnabled(false); //Or remove picasso.setIndicatorsEnabled(true);
Check this: Is there any way from which we can detect images are loading from cache in picasso?
How can I add the Progress dialog in ImageView until I loading image from server in android. When image download complete then display the image.
try {
cachedImage = imageLoader.loadImage(mTopicList.getTopicImage(j),
new ImageLoadedListener() {
public void imageLoaded(Bitmap imageBitmap)
{
imageView.setImageBitmap(imageBitmap);
imageView.invalidate();
}
});
} catch (Exception e) {
e.printStackTrace();
}
Approach which I followed to do this. Use the Frame Layout and have a ImageView and ProgressBar inside it. I've used the Universal Image Loader Library, which have callback once image has been downloaded. Initially show the ProgressBar and hide the ImageView to invisible. Once image has been downloaded then hide the ProgressBar and show the image in the ImageView.
Initially
imageView.setVisibility(View.INVISIBLE);
progressBar.setVisibility(View.VISIBLE);
Load your image now. After loading it, call this:
progressBar.setVisibility(View.INVISIBLE);
imageView.setVisibility(View.VISIBLE);
Hope this help to you all!
I want to do an image gallery like in iphone. I want to show low quality (pre-resized) images and when the image is active I want to process the big image and show the result in the gallery.
I have two questions. How to attach a listener on the animation stop in gallery? And how to access an image after this action?
You can set an AnimationListener on your animation, and override the onAnimationEnd method.
From http://www.roosmaa.net/animation-ended-callback/ :
ImageView viewN = ..;
Animation animN = ...;
Drawable myNewDrawable = ...;
animN.setAnimationListener(new AnimationListener() {
// ...
void onAnimationEnd(Animation anim)
{
//Do your work here.
viewN.setDrawable(myNewDrawable);
return;
}
// ...
});
viewN.startAnimation(animN);