Подтвердить что ты не робот

Android Volley - как оживить загрузку изображения?

любая идея, как играть в анимацию при анимации изображения? Теперь он просто мерцает на месте. Я использую NetworkImageView из инструментария Volley.

Кроме того, есть ли способ установить растровые изображения загрузки и ошибки в представлении сетевого изображения без использования ImageLoader.get(..)?

Спасибо!

//EDIT: Хорошо, спасибо вам всем, но если мы хотим быть перфекционистами, мы должны только анимировать, если загрузка с дискового кэша, переопределение setImageBitmap приведет к тому, что анимация будет отключена, даже если вы вытащить из memcache

то, что вы хотите сделать, это добавить булевский 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);
      ...
   }
}

Я создал использование Gist для копирования и вставки - https://gist.github.com/ursusursus/5732521

4b9b3361

Ответ 1

Пример реализации ответа CommonsWare можно найти здесь: https://gist.github.com/benvd/5683818.

С помощью TransitionDrawable добавляется дополнительный слой overdraw. Если вы хотите этого избежать, возможно, использование ViewPropertyAnimator может помочь.

Суть его в основном состоит в следующем фрагменте в 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

любая идея, как играть в анимацию при анимации изображения? Теперь он просто мерцает на месте. Я использую NetworkImageView из инструментария Volley.

Выключите манжету, создайте свой собственный подкласс NetworkImageView и переопределите setImageBitmap(), чтобы настроить альфа-анимацию при использовании изображения.

Кроме того, есть ли способ установить растровые изображения загрузки и ошибки в представлении сетевого изображения без использования ImageLoader.get(..)?

Вызовите setImageBitmap() или setImageResource(), так же, как и с обычным ImageView.

Ответ 3

Это моя реализация анимационного 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);
    }
}

Надеюсь, это поможет кому-то!

Ответ 4

Кроме того, существует ли способ установить загрузочные и ошибочные растровые изображения в сети изображения без использования ImageLoader.get(..)?

В NetworkImageView есть методы для этих двух операций:

mNetworkImageView.setErrorImageResId(R.drawable.errorImageResourceId);
mNetworkImageView.setDefaultImageResId(R.drawable.loadingImageResourceId);

Ответ 5

Эта версия NetworkImageView проверяет ImageLoader по URL-адресу, если изображение находится в кеше и отключает анимацию. В отличие от @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);
    }
}

Ответ 6

Я рекомендую использовать Picasso lib для загрузки изображений или Glide. для загрузки изображений + анимация использует Picasso с этим lib: 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() {

        }
    });

Если вы, возможно, захотите, чтобы какой-то файл auth для загрузки изображений использовал 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);

кроме того, у Пикассо для файла auth есть вещи-перехватчики, но я использовал Glide. возможно, это помогает..