问题
any idea how to play a fade in animation when image loads? Now it just blinks into place. I am using NetworkImageView from the Volley toolkit.
Also, is there a way to set loading and error bitmaps on the network image view without using the ImageLoader.get( .. ) ?
Thanks!
//EDIT: Okay, thanks to you all, but if we want to be perfectionists, we should only animate if loading from disk cache, overriding setImageBitmap would case animation to go off even if pulled from memcache
what you want to do is add a boolean shouldAnimate
to ImageListener.onResponse like this
public static ImageListener getImageListener(final ImageView view, final int defaultImageResId,
final int errorImageResId) {
return new ImageListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (errorImageResId != 0) {
view.setImageResource(errorImageResId);
}
}
@Override
public void onResponse(ImageContainer response, boolean isImmediate, boolean shouldAnimate) {
if (response.getBitmap() != null) {
if (shouldAnimate) {
// ADDED
view.setAlpha(0f);
view.setImageBitmap(response.getBitmap());
view.animate().alpha(1f).setDuration(1000);
// END ADDED
} else {
view.setImageBitmap(response.getBitmap());
}
} else if (defaultImageResId != 0) {
view.setImageResource(defaultImageResId);
}
}
};
}
this is a method that sets the bitmap, no matter where it is from, so you need to set it to false to every usage in ImageLoader except for
class BatchedImageRequest {
private void batchResponse(String cacheKey, BatchedImageRequest request,
final VolleyError error) {
...
container.mListener.onResponse(container, false, true);
...
}
}
I've created a Gist for Copy & Paste usage - https://gist.github.com/ursusursus/5732521
回答1:
Example implementation of CommonsWare's answer can be found here: https://gist.github.com/benvd/5683818.
Using a TransitionDrawable
does add an extra layer of overdraw. If you want to avoid that, perhaps using a ViewPropertyAnimator
might help.
The gist of it is basically to have the following snippet in your setImageBitmap()
:
TransitionDrawable td = new TransitionDrawable(new Drawable[]{
new ColorDrawable(android.R.color.transparent),
new BitmapDrawable(getContext().getResources(), bm)
});
setImageDrawable(td);
td.startTransition(FADE_IN_TIME_MS);
回答2:
any idea how to play a fade in animation when image loads? Now it just blinks into place. I am using NetworkImageView from the Volley toolkit.
Off the cuff, create your own subclass of NetworkImageView
and override setImageBitmap()
to set up the alpha animation when the image is applied.
Also, is there a way to set loading and error bitmaps on the network image view without using the ImageLoader.get( .. ) ?
Call setImageBitmap()
or setImageResource()
, the same way you would with a regular ImageView
.
回答3:
This is my implementation of an animating NetworkImageView. It uses ObjectAnimator to fade in newly downloaded images, while cached images appear immediately. The implementation is pretty simple - only requiring you to override two NetworkImageView methods (setImageBitmap(Bitmap) and setImageUrl(String, ImageLoader). It uses the supplied ImageLoader to determine if the image is from cache.
public class AnimatedNetworkImageView extends NetworkImageView {
private static final int ANIM_DURATION = 500;
private boolean shouldAnimate = false;
public AnimatedNetworkImageView(Context context) {
super(context);
}
public AnimatedNetworkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AnimatedNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
if(shouldAnimate) {
ObjectAnimator.ofFloat(this, "alpha", 0, 1).setDuration(ANIM_DURATION).start();
}
}
@Override
public void setImageUrl(String url, ImageLoader imageLoader) {
shouldAnimate = !imageLoader.isCached(url, 0, 0);
super.setImageUrl(url, imageLoader);
}
}
Hope this helps someone!
回答4:
Also, is there a way to set loading and error bitmaps on the network image view without using the ImageLoader.get( .. ) ?
NetworkImageView has methods for these two operations :
mNetworkImageView.setErrorImageResId(R.drawable.errorImageResourceId);
mNetworkImageView.setDefaultImageResId(R.drawable.loadingImageResourceId);
回答5:
This version of the NetworkImageView
checks the ImageLoader upon url set if the image is in the cache and disables the animation. In contrast to @DalvikDroid answer this also respects the with/height/scalingType parameter for the cache.
/**
* NetworkImageView that fades-in the drawable upon complete download
*/
public class AnimatedNetworkImageView extends NetworkImageView {
private static final int ANIM_DURATION = 500;
private boolean shouldAnimate = true;
public AnimatedNetworkImageView(Context context) {
super(context);
init();
}
public AnimatedNetworkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AnimatedNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
shouldAnimate = true; // animate by default. Only when {@link #determineIfAnimationIsNecessary} is called animation is dependent upon cache status
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
if (shouldAnimate) {
// your animation. Here with ObjectAnimator for example
ObjectAnimator.ofFloat(this, "alpha", 0, 1).setDuration(ANIM_DURATION).start();
}
}
@Override
public void setImageUrl(String url, ImageLoader imageLoader) {
shouldAnimate = determineIfAnimationIsNecessary(url, imageLoader);
super.setImageUrl(url, imageLoader);
}
/**
* checks if for the given imgUrl and imageLoader the view should animate when a bitmap is set.
* If this method is called before {@link NetworkImageView#setImageUrl(String, ImageLoader)} is called the view would not be animated if the image comes from the cache.
*
* @param imgUrl the image url
* @param imageLoader the image loader
*/
public boolean determineIfAnimationIsNecessary(String imgUrl, ImageLoader imageLoader) {
int width = getWidth();
int height = getHeight();
ScaleType scaleType = getScaleType();
boolean wrapWidth = false, wrapHeight = false;
if (getLayoutParams() != null) {
wrapWidth = getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT;
wrapHeight = getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT;
}
// Calculate the max image width / height to use while ignoring WRAP_CONTENT dimens.
int maxWidth = wrapWidth ? 0 : width;
int maxHeight = wrapHeight ? 0 : height;
return !imageLoader.isCached(imgUrl, maxWidth, maxHeight, scaleType);
}
}
回答6:
i recommend to use Picasso lib for loading images or Glide. for loading images + animation use Picasso with this lib: com.github.florent37:materialimageloading solution like this..
Picasso.with(this).load(bannerUrl).fit().centerCrop().into(bannerImage, new Callback() {
@Override
public void onSuccess() {
MaterialImageLoading.animate(bannerImage).setDuration(2000).start();
}
@Override
public void onError() {
}
});
if you maybe want some auth stuff for image loading use Glide like this..
GlideUrl glideUrl = new GlideUrl(bannerUrl, new LazyHeaders.Builder()
.addHeader("username", "heyyou")
.addHeader("password", "heyyou")
.build());
Glide.with(this).load(bannerUrl)
.centerCrop()
.crossFade(5000)
.into(bannerImage);
in addition Picasso for auth stuff have interceptor things but i used Glide. maybe this helps..
来源:https://stackoverflow.com/questions/16778274/android-volley-how-to-animate-image-loading