package com.annimon.everlastingsummer; import java.util.Locale; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.util.AttributeSet; import android.util.SparseArray; import android.widget.ImageView; import com.annimon.everlastingsummer.drawables.TransitionAnimationDrawable; import com.annimon.everlastingsummer.transitions.Dissolve; import com.annimon.everlastingsummer.transitions.Fade; import com.annimon.everlastingsummer.transitions.Transition; import com.annimon.everlastingsummer.transitions.Transitions; /** * ImageView с поддержкой анимации переходов. * @author aNNiMON */ public class AnimatableImageView extends ImageView { private static final ColorDrawable NONE = new ColorDrawable(); private static final SparseArray colors; static { colors = new SparseArray(); colors.append(0, NONE); colors.append(Color.WHITE, new ColorDrawable(Color.WHITE)); colors.append(Color.BLACK, new ColorDrawable(Color.BLACK)); colors.append(0xFFEE1111, new ColorDrawable(0xFFEE1111)); } private Drawable previous; public AnimatableImageView(Context context) { super(context); } public AnimatableImageView(Context context, AttributeSet attrs) { super(context, attrs); } public AnimatableImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public void setImageResource(int resId) { setImageResource(resId, ""); } public int setImageResource(int resId, String effect) { previous = getDrawable(); super.setImageResource(resId); return setAnimationEffect(effect); } @Override public void setImageDrawable(Drawable drawable) { setImageDrawable(drawable, ""); } public int setImageDrawable(Drawable drawable, String effect) { previous = getDrawable(); super.setImageDrawable(drawable); return setAnimationEffect(effect); } @Override public void setImageBitmap(Bitmap bm) { setImageBitmap(bm, ""); } public int setImageBitmap(Bitmap bm, String effect) { previous = getDrawable(); super.setImageBitmap(bm); return setAnimationEffect(effect); } @Override public Drawable getDrawable() { final Drawable result = super.getDrawable(); if (result == null) return new ColorDrawable(); if (result instanceof LayerDrawable) { final LayerDrawable ld = (LayerDrawable) result; return ld.getDrawable(ld.getNumberOfLayers() - 1); } return result; } public void hideDrawable(String effect, Runnable runnable) { final int delay = setImageDrawable(NONE, effect); if (delay == 0) runnable.run(); else { postDelayed(runnable, delay); } } private int setAnimationEffect(String animEffect) { final String effect = animEffect.toLowerCase(Locale.ENGLISH); if (!Transitions.contains(effect)) return 0; final Transition transition = Transitions.get(effect); switch (transition.type()) { case Transition.TYPE_FADE: { final TransitionAnimationDrawable drawable = fade((Fade) transition); setImageDrawable(drawable); drawable.startTransition(); return drawable.getFullDuration(); } case Transition.TYPE_DISSOLVE: { final Dissolve dissolve = (Dissolve) transition; final int delay = dissolve.getDelay(); final TransitionAnimationDrawable drawable = new TransitionAnimationDrawable(delay, previous, getDrawable()); setImageDrawable(drawable); drawable.setCrossFadeEnabled(true); drawable.startTransition(); return drawable.getFullDuration(); } default: return 0; } } private TransitionAnimationDrawable fade(Fade fade) { final int fadeColor = fade.getColor(); // Достаём ColorDrawable из кэша или создаём новый и кладём в кэш Drawable fadeColorDrawable; if (colors.indexOfKey(fadeColor) < 0) { fadeColorDrawable = new ColorDrawable(fadeColor); colors.put(fadeColor, fadeColorDrawable); } else { fadeColorDrawable = colors.get(fadeColor); } final TransitionAnimationDrawable.Builder builder = new TransitionAnimationDrawable.Builder(); builder.add(0, previous); // img1 -> color builder.add(fade.getOutTime(), fadeColorDrawable); if (fade.getHoldTime() > 0) { // color ~ color builder.add(fade.getHoldTime(), new ColorDrawable(fadeColor)); // копия обязательна! } // color -> img2 builder.add(fade.getInTime(), getDrawable()); return builder.build(); } }