My question is about how to achieve a well-performing animation for a set of ImageView
s, so that the foreground fades away and the background stays the same.
Currently, I'm writing a clone of "Color Lines" for Android using a GridLayout
as a board and ImageView
s as game pieces. Every ImageView
uses the same (circular) ShapeDrawable
:
ImageView ivChild.setImageResource(R.drawable.circle_shape);
where circle_shape.xml looks like this:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<gradient
android:angle="0"
android:centerColor="#eeeeee"
android:centerX="0.0"
android:centerY="0.0"
android:endColor="#bbbbbb"
android:startColor="#dddddd"
android:type="sweep" />
</shape>
and another drawable resource as a background to get a board with tiles separated by thin lines (I'm using a rectangle shape with a color gradient and set a margin to the ImageView
s).
To show the differently colored items as well as the empty fields, I simply use setColorFilter()
with different color resources (#00000000 for empty fields)
Every time the user completes a line of five or more items with the same color, I want to show an animation (color fading away) instead of just setting the color to transparent. I could simply use a ViewAnimation
(alpha) if the whole View
was to fade away but as I said I need to keep the background unchanged and just animate the foreground.
The following method is part of the Fragment
which is hosting the board:
void clearPositions(int[] completedLinesPositions, color)
{
ImageView[] fields = new ImageView[completedLinesPositions.length];
for (int i = 0; i < completedLinesPositions.length; i++)
{
// board is the GridLayout
fields[i] = (ImageView) board.getChildAt(positions[i]);
}
ValueAnimator animation = ValueAnimator.ofObject(new FloatEvaluator(), 1.0f, 0f);
ValueAnimator.AnimatorUpdateListener myUpdateListener = new MyAlphaUpdateListener(fields, color);
animation.addUpdateListener(myUpdateListener);
animation.setDuration(200);
animation.start();
int empty = Color.argb(0, 0, 0, 0);
for (ImageView iv: fields )
{
iv.clearColorFilter();
iv.setColorFilter(empty, PorterDuff.Mode.MULTIPLY);
}
}
The MyAlphaUpdateListener
:
public class MyAlphaUpdateListener implements ValueAnimator.AnimatorUpdateListener {
private ImageView[] imageViews;
private int red, blue, green;
MyAlphaUpdateListener(ImageView[] ivs, int color) {
imageViews = ivs;
red = Color.red(color);
green = Color.green(color);
blue = Color.blue(color);
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Object o = animation.getAnimatedValue();
int newalpha = (int) (255 * (float) o);
int newColor = Color.argb(newalpha, red, green, blue);
for (ImageView imageView : imageViews) {
imageView.clearColorFilter();
imageView.setColorFilter(newColor, PorterDuff.Mode.MULTIPLY);
}
}
}
As you can imagine, this will run quite often so I'd like to achieve a good performance. There seem to be no skipped frames but I also want to be as easy on the battery as possible. Is there anything I can do to reduce CPU time?