/** * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Added by Vinay S Shenoy on 19/5/13 */ package com.android.volley.toolbox; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.net.Uri; import android.util.AttributeSet; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.ImageView; import com.vinaysshenoy.volleyenhanced.R; /** * Created by vinaysshenoy on 19/5/13. */ public class AnimateImageView extends ImageView implements Animation.AnimationListener{ /** * Whether changes to this imageview * should be animated or not */ private boolean mShouldAnimateChanges; /** * The animation when adding in the new image */ private Animation mInAnimation; /** * The animation when removing the older image */ private Animation mOutAnimation; /** * The different types of image resources * possible. Used to animate the images * when changing */ private static interface ImageType { public static final int URI = 1; public static final int BITMAP = 2; public static final int DRAWABLE = 3; public static final int RESOURCE = 4; } private int mInImageType; /** * The Image Ids to be used when the * out animation ends and the fade animation begins */ private Uri mInImageUri; private Bitmap mInBitmap; private Drawable mInDrawable; private int mInResId; public AnimateImageView(Context context) { this(context, null); init(context, null); } public AnimateImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); init(context, attrs); } public AnimateImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context, attrs); } private void init(Context context, AttributeSet attrs) { if(attrs == null) { initializeWithDefaults(); } else { TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.AnimateImageView); if(attributes == null) { initializeWithDefaults(); } else { mShouldAnimateChanges = attributes.getBoolean(R.styleable.AnimateImageView_animate_changes, false); int inAnimationResId = attributes.getResourceId(R.styleable.AnimateImageView_in_animation, 0); int outAnimationResId = attributes.getResourceId(R.styleable.AnimateImageView_out_animation, 0); attributes.recycle(); if(inAnimationResId == 0) { mInAnimation = new AlphaAnimation(0.0f, 1.0f); mInAnimation.setDuration(400); mInAnimation.setFillAfter(true); } else { mInAnimation = AnimationUtils.loadAnimation(context, inAnimationResId); } if(outAnimationResId == 0) { mOutAnimation = new AlphaAnimation(1.0f, 0.0f); mOutAnimation.setDuration(150); mOutAnimation.setFillAfter(true); } else { mOutAnimation = AnimationUtils.loadAnimation(context, outAnimationResId); } mInAnimation.setAnimationListener(this); mOutAnimation.setAnimationListener(this); } } } private void initializeWithDefaults() { mShouldAnimateChanges = false; mInAnimation = null; mOutAnimation = null; } /** * Whether any changes to this ImageView should be animated * @param animateChanges whether to animate the changes or not */ public void setShouldAnimateChanges(boolean animateChanges) { mShouldAnimateChanges = animateChanges; } /** * The animation to use when adding a new image * @param inAnimation The animation to add an image */ public void setInAnimation(Animation inAnimation) { mInAnimation = inAnimation; } /** * The animation to use when removing the older image * @param outAnimation The animation to remove an image */ public void setOutAnimation(Animation outAnimation) { mOutAnimation = outAnimation; } @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { if(animation == mOutAnimation) { switch(mInImageType) { case ImageType.URI: { setImageURI(mInImageUri); break; } case ImageType.BITMAP: { setImageBitmap(mInBitmap); break; } case ImageType.DRAWABLE: { setImageDrawable(mInDrawable); break; } case ImageType.RESOURCE: { setImageResource(mInResId); break; } default: { throw new RuntimeException("Unknown image type"); } } startAnimation(mInAnimation); } if(animation == mOutAnimation) { switch(mInImageType) { case ImageType.URI: { mInImageUri = null; break; } case ImageType.BITMAP: { mInBitmap = null; break; } case ImageType.DRAWABLE: { mInDrawable = null; break; } case ImageType.RESOURCE: { mInResId = 0; break; } default: { throw new RuntimeException("Unknown image type"); } } mInImageType = 0; } } @Override public void onAnimationRepeat(Animation animation) { } public void setImageResource(int resId, boolean animate) { if(mShouldAnimateChanges & animate) { mInImageType = ImageType.RESOURCE; mInResId = resId; startAnimation(mOutAnimation); } else { super.setImageResource(resId); } } public void setImageURI(Uri uri, boolean animate) { if(mShouldAnimateChanges & animate) { mInImageType = ImageType.URI; mInImageUri = uri; startAnimation(mOutAnimation); } else { super.setImageURI(uri); } } public void setImageDrawable(Drawable drawable, boolean animate) { if(mShouldAnimateChanges & animate) { mInImageType = ImageType.DRAWABLE; mInDrawable = drawable; startAnimation(mOutAnimation); } else { super.setImageDrawable(drawable); } } public void setImageBitmap(Bitmap bm, boolean animate) { if(mShouldAnimateChanges & animate) { mInImageType = ImageType.BITMAP; mInBitmap = bm; startAnimation(mOutAnimation); } else { super.setImageBitmap(bm); } } }