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
Ответы
Ответ 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.
возможно, это помогает..