13

知道如何在图像加载时播放淡入淡出的动画吗?现在它只是闪烁到位。我正在使用 Volley 工具包中的 NetworkImageView。

另外,有没有办法在不使用 ImageLoader.get(..) 的情况下在网络图像视图上设置加载和错误位图?

谢谢!

//编辑好的,谢谢大家,但是如果我们想成为完美主义者,我们应该只在从磁盘缓存加载时进行动画处理,覆盖 setImageBitmap 会导致即使从内存缓存中提取动画也会消失

你想要做的是shouldAnimate像这样向 ImageListener.onResponse添加一个布尔值

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);
            }
        }
    };
}

这是一个设置位图的方法,无论它来自哪里,所以你需要将它设置为 false 到 ImageLoader 中的每个用法,除了

class BatchedImageRequest {

   private void batchResponse(String cacheKey, BatchedImageRequest request,
        final VolleyError error) {
      ...
      container.mListener.onResponse(container, false, true);
      ...
   }
}

我创建了一个用于复制和粘贴的要点 - https://gist.github.com/ursusursus/5732521

4

6 回答 6

23

可以在此处找到 CommonsWare 答案的示例实现:https ://gist.github.com/benvd/5683818 。

使用 aTransitionDrawable确实增加了一层额外的透支。如果您想避免这种情况,也许使用 aViewPropertyAnimator可能会有所帮助。

它的要点基本上是在您的 中包含以下代码段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);
于 2013-06-05T09:43:00.627 回答
6

知道如何在图像加载时播放淡入淡出的动画吗?现在它只是闪烁到位。我正在使用 Volley 工具包中的 NetworkImageView。

即兴创作,创建您自己的子类NetworkImageView并覆盖setImageBitmap()以在应用图像时设置 alpha 动画。

另外,有没有办法在不使用 ImageLoader.get(..) 的情况下在网络图像视图上设置加载和错误位图?

呼叫setImageBitmap()or setImageResource(),与普通ImageView.

于 2013-05-27T18:10:41.630 回答
5

这是我对动画 NetworkImageView 的实现。它使用 ObjectAnimator 淡入新下载的图像,而缓存的图像立即出现。实现非常简单——只需要你重写两个 NetworkImageView 方法(setImageBitmap(Bitmap) 和 setImageUrl(String, ImageLoader)。它使用提供的 ImageLoader 来确定图像是否来自缓存。

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);
    }
}

希望这对某人有帮助!

于 2014-05-03T01:49:55.560 回答
1

另外,有没有办法在不使用 ImageLoader.get(..) 的情况下在网络图像视图上设置加载和错误位图?

NetworkImageView 有这两个操作的方法:

mNetworkImageView.setErrorImageResId(R.drawable.errorImageResourceId);
mNetworkImageView.setDefaultImageResId(R.drawable.loadingImageResourceId);
于 2013-08-30T13:23:53.127 回答
0

我建议使用 Picasso lib 来加载图像或 Glide。加载图像+动画使用 Picasso 和这个库:com.github.florent37:materialimageloading 像这样的解决方案..

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() {

        }
    });

如果您可能想要一些用于图像加载的身份验证内容,请像这样使用 Glide..

        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);

此外,毕加索用于身份验证的东西有拦截器的东西,但我使用了 Glide。也许这有帮助..

于 2015-07-30T16:31:11.503 回答
0

NetworkImageView如果图像在缓存中并禁用动画,则此版本会根据 url 设置检查 ImageLoader。与@DalvikDroid 答案相反,这也尊重缓存的 with/height/scalingType 参数。

/**
 * 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);
    }
}
于 2015-12-14T11:45:06.977 回答