2
\$\begingroup\$

I created a loader animation for an Android app: a simple 3 dots loader.

Is this the correct way to animate by using TimerTask?

public class ThreeDotsLoader extends View {

    Paint dot1;
    Paint dot2;
    Paint dot3;

    int defaultColor;
    int highlightColor;

    boolean animationStarted = false;

    TimerTask task;
    Timer timer;

    int count = 1;

    public ThreeDotsLoader(Context context, AttributeSet attrs) {
        super(context, attrs);
        defaultColor = Color.rgb(44, 78, 82);
        highlightColor = Color.WHITE;

        initPaint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d("custom", "ondraw");
        canvas.drawCircle(50, 50, 15, dot1);
        canvas.drawCircle(100, 50, 15, dot2);
        canvas.drawCircle(150, 50, 15, dot3);
    }

    private void initPaint(){
        dot1 = new Paint();
        dot1.setColor(defaultColor);
        dot1.setStyle(Paint.Style.FILL);
        dot1.setAntiAlias(true);


        dot2 = new Paint();
        dot2.setColor(defaultColor);
        dot2.setStyle(Paint.Style.FILL);
        dot2.setAntiAlias(true);

        dot3 = new Paint();
        dot3.setColor(defaultColor);
        dot3.setStyle(Paint.Style.FILL);
        dot3.setAntiAlias(true);
    }

    public void startLoading(){
        task = new TimerTask() {

            @Override
            public void run() {

                switch(count){
                case 1:
                    dot1.setColor(highlightColor);
                    dot2.setColor(defaultColor);
                    dot3.setColor(defaultColor);
                    count++;
                    break;
                case 2:
                    dot1.setColor(defaultColor);
                    dot2.setColor(highlightColor);
                    dot3.setColor(defaultColor);
                    count++;
                    break;
                case 3:
                    dot1.setColor(defaultColor);
                    dot2.setColor(defaultColor);
                    dot3.setColor(highlightColor);
                    count = 1;
                    break;
                }
                animationStarted = true;
                postInvalidate();
            }
        };
        timer = new Timer();
        timer.schedule(task, 0, 300);

    }

    public void stopLoading(){
        animationStarted = false;
        timer.cancel();
    }
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I would avoid "new Timer();" for this use case. The timer task it changing the paint object on a thread other than the main UI thread, which is very likely to lead to non-deterministic behavior.

I recommend using an ObjectAnimator ( see the Property animation guide )

If you need to support pre-API 11 releases, you can use NineOldAndroids.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.