I'm displaying multiple images from our server as a slideshow with a ImageSwitcher. Before the ImageSwitcher gets initialized I want to preload the images with Picasso library.
I want to say that I use Picasso with an interceptor, because our server requires Basic Authentication for the images.
My current preloading:
final int[] downloadedCounter = {0};
for (int i = 0; i < images.size(); i++) {
final SlideshowImage image = images.get(i);
PicassoUtils.getPicassoWithBasicAuthorizationFrom(user, getContext())
.load(image.getImageUrl())
.fetch(new Callback() {
#Override
public void onSuccess() {
downloadedCounter[0]++;
if (downloadedCounter[0] == images.size()) {
callback.downloadFinished();
}
}
#Override
public void onError() {
}
});
}
And that is my ImageSwitcher:
ImageView image = (ImageView) this.getNextView();
PicassoUtils.getPicassoWithBasicAuthorizationFrom(user, getContext())
.load(imageUrl)
.noFade()
.into(image, new Callback() {
#Override
public void onSuccess() {
showNext();
}
#Override
public void onError() {
}
});
But the problem is, that it won't get cached, because when I use .networkPolicy(NetworkPolicy.OFFLINE) on Picasso in my ImageSwitcher nothing gets loaded.
And everytime i call showNext() in my ViewSwitcher the used memory of the device rises a bit.
Related
im using Glide library to load my images from storage to imageView using RecyclerView
all thing good
but when number of images be alot app crashed or should be wait so much to activity load completely
this is my code
public static File DIR_IMG = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "MyHairSamples");
private void readExistingImages(){
File[] images;
try {
images= DIR_IMG.listFiles();
for (int i = 0; i < images.length; i++) {
if (images[i].isFile() && images[i].length() > 50L) {
Bitmap b = BitmapFactory.decodeFile(images[i].getAbsolutePath());
addImage(b, "5", images[i].getName());
}
else{
images[i].delete();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
and i using this method in onCreate method
and this is my Adapter Code
#Override
public void onBindViewHolder(#NonNull MyViewHolder viewHolder, int i) {
viewHolder.title.setText(arrayList.get(i).getImageTitle());
viewHolder.thumbnail.setLabelFor(i);
Glide.with(context)
.load(arrayList.get(i).getImage())
.into(viewHolder.thumbnail);
}
When the images resolution is big, loading will be slow and even your application will crash.
So you can resize your image set like this
Glide.with(context)
.load(arrayList.get(i).getImage())
.apply(new RequestOptions().override(400, 400))
.into(viewHolder.thumbnail);
EDIT
RequestOptions reqOpt = RequestOptions
.fitCenterTransform()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.override(300,300)
Load images inside the uithread, it is not interrupt the main thread.
Use below code.
context.runOnUiThread(new Runnable() {
#Override
public void run() {
Glide.with(context)
.load(arrayList.get(i).getImage())
.into(viewHolder.thumbnail);
}
});
My problem statement is to load the images from the server.
Now I have used picasso inside the custom adapter.
The image which I am downloading its size is approximately 100kb
not more than that.But instead of displaying the image white background is
been displayed.
To check error I have used callback but somehow the callback is not working
I mean the callback is never getting called.
Below is my code
#Override
public void onBindViewHolder(FolderListAdapter.Viewholder holder, int position) {
userDetails=userList.get(position);
//Context context=);
if(userDetails.getLogo()!=null && !userDetails.getLogo().isEmpty()) {
Context context=holder.cardProfilePic.getContext();
Picasso.with(context)
.load(userDetails.getLogo())
.fit()
.into(holder.cardProfilePic, new Callback() {
#Override
public void onSuccess() {
Log.d("succes","success");
}
#Override
public void onError() {
Log.d("failure","failure");
}
});
}
if(userDetails.getBanner()!=null && !userDetails.getBanner().isEmpty()) {
Picasso.with(context)
.load(userDetails.getBanner())
.resize(300,300)
.into(holder.cardBackgroundPic);
}
if(userDetails.getPersonName()!=null && !userDetails.getPersonName().isEmpty()) {
holder.username.setText(userDetails.getPersonName());
}
if(userDetails.getDesignation()!=null && !userDetails.getDesignation().isEmpty()) {
holder.userRole.setText(userDetails.getDesignation());
}
}
I want before render MainActivity check what all pictures is loaded:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
getBitmapsByURLs(urls);
}
public void getBitmapsByURLs(List<String> urls) {
final List<Target> targets = new ArrayList<>();
for (int i = 0; i < urls.size(); i++) {
final int k = i;
Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Log.i("TEMP", "Loaded: " + k);
targets.remove(this);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
targets.remove(this);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.i("TEMP", "Preparing: " + k);
}
};
targets.add(target);
Picasso.with(this)
.load(urls.get(i))
.memoryPolicy(NO_CACHE, NO_STORE)
.into(target);
}
}
How I can check inside onCreate what all pictures is loaded?
If I write while on method onCreate (after call getBitmapsByURLs) then it will be called before all pictures are loaded.
You must be known that when you use
Picasso.with(this)
.load(urls.get(i))
.memoryPolicy(NO_CACHE, NO_STORE)
.into(target);
to load a picture,it is a asynchronized task.First picasso download the picture from internet.After downloading is finished,the picture will be loaded into target.Of course,when downloading,the main thread will never be waiting.Picasso use something like Observer-Subcriber or interface Future to make the main thread informed that downing is over.Above all,no matter what you write after getBitmapsByURLs(urls),it will be called before picasso finishes loading pictures.(Because it usually costs some more time to download pictures and load them into targets).
What's more.This is not a recommended way to do such a time-costing work in onCreate().Because onCreate() is called in main thread.If you do something costs much time here,then you will get an Application Not Responding error.
I have this method, everything is worked perfectly but images always got from server and not load from cache! what happened ?
public static void makeImageRequest(String Unique_ID, final View parentView, final int id) {
String url = FILE_UPLOAD_FOLDER + Unique_ID + ".png";
final int defaultImageResId = R.drawable.user;
// Retrieves an image specified by the URL, displays it in the UI.
ImageCacheManager.getInstance().getImage(url, new ImageListener() {
#Override
public void onErrorResponse(VolleyError error) {
ImageView imageView = (ImageView) parentView.findViewById(id);
imageView.setImageResource(defaultImageResId);
}
#Override
public void onResponse(ImageContainer response, boolean isImmediate) {
if (response.getBitmap() != null) {
ImageView imageView = (ImageView) parentView.findViewById(id);
imageView.setImageBitmap(response.getBitmap());
} else if (defaultImageResId != 0) {
ImageView imageView = (ImageView) parentView.findViewById(id);
imageView.setImageResource(defaultImageResId);
}
}
});
}
Just use Picasso instead ImageCacheManager. Picasso is a powerful image downloading and caching library for Android. Images add much-needed context and visual flair to Android applications. Picasso allows for hassle-free image loading in your application—often in one line of code!
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
Here also can manage whether the image is successfully downloaded or it fails:
Picasso.with(context)
.load("http://i.imgur.com/DvpvklR.png")
.into(imageView, new Callback() {
#Override
public void onSuccess() {
// your code
}
#Override
public void onError() {
// your code
}
});
You should only add this line in your gradle:
compile 'com.squareup.picasso:picasso:2.5.2'
Hope it helps!
I want to show a fade effect when image is loading on Imageview. I am using picasso to cache image and display in image view. I have searched alot for this but couldnt find any solution.
I have used earlier before and i know in some version they had .fade(int Duration) method to fade image while loading but i couldnt find this method anymore.
Here is what i am doing now
Picasso.with(context)
.load(viewHolder.data.imageList.get(0).url)
.networkPolicy(NetworkPolicy.OFFLINE)
.placeholder(R.drawable.a_place_holder_list_view)
.error(R.drawable.a_place_holder_list_view)
.into(viewHolder.ivUser, context.loadImage(viewHolder.ivUser, viewHolder.data.imageList.get(0).url));
public Callback loadImage(RoundedImageView ivUser, String url) {
return new callback(ivUser, url);
}
public class callback implements Callback {
RoundedImageView imageView;
String url;
public callback(RoundedImageView imageView, String url) {
this.imageView = imageView;
this.url = url;
}
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(BaseActivity.this)
.load(url)
.placeholder(R.drawable.a_place_holder_list_view)
.error(R.drawable.a_place_holder_list_view)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Log.v("Picasso", "Could not fetch image");
}
});
}
}
Please help me i have been stuck in this for quite long time.
Thanks in advance.
Quoting Jake Wharton's answer here:
If the image comes from anywhere except the memory cache the fade
should be automatically applied.
If you check the PicassoDrawable class
boolean fade = loadedFrom != MEMORY && !noFade;
if (fade) {
this.placeholder = placeholder;
animating = true;
startTimeMillis = SystemClock.uptimeMillis();
}
.
.
.
#Override public void draw(Canvas canvas) {
if (!animating) {
super.draw(canvas);
} else {
.
.
.
fade effect is already applied for images loaded from n/w and not memory/cache
and FADE_DURATION = 200f; //ms
To force fade, again quoting jake wharton's answer here:
You can specify noFade() and then always play an animation in the
image loaded callback. You can also rely on the callback being called
synchronously to determine if an animation needs played.
final AtomicBoolean playAnimation = new AtomicBoolean(true);
Picasso.with(context).load(..).into(imageView, new Callback() {
#Override public void onLoad() {
if (playAnimation.get()) {
//play fade
Animation fadeOut = new AlphaAnimation(0, 1);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setDuration(1000);
imageView.startAnimation(fadeOut);
Animation fadeOutPlaceholder = new AlphaAnimation(1, 0);
fadeOutPlaceholder.setInterpolator(new AccelerateInterpolator());
fadeOutPlaceholder.setDuration(1000);
placeHolderImageView.startAnimation(fadeOutPlaceholder);
}
}
//..
});
playAnimation.set(false);
You can simply do
Picasso.with(context).load(url).fetch(new Callback(){
#Override
public void onSuccess() {
imageView.setAlpha(0f);
Picasso.with(context).load(url).into(imageView);
imageView.animate().setDuration(300).alpha(1f).start();
}
#Override
public void onError() {
}
});
I do this:
Picasso.get().load(url).fit().noFade().centerInside().into(imageView, new Callback() {
#Override
public void onSuccess() {
imageView.setAlpha(0f);
imageView.animate().setDuration(200).alpha(1f).start();
}
#Override
public void onError(Exception e) {
}
});