Android Canvas:触摸后绘制一条淡化/ alphaAnimation线

时间:2011-10-25 14:46:51

标签: java android android-canvas

我有一个Canvas,我在onTouchEvent()上画了几行。当用户对放置线的位置进行无效选择时,我绘制的是红线而不是黑线。但是我希望红线在接下来的500-1000毫秒内逐渐消失。

我无法弄明白该怎么做,如果甚至可以在Canvas内为单行制作动画。

我在我的3个不同位图之间拆分了点,有效的黑线和无效的红线:

public void onDraw(Canvas canvas) {
    // Fade Red Line
    canvas.drawBitmap(fBitmap, 0, 0, null);
    // Lines
    canvas.drawBitmap(mBitmap, 0, 0, null);
    // Dots
    canvas.drawBitmap(iBitmap, 0, 0, null); 
}

我的onTouch函数内部是drawLines()

我想知道我是否可以使用AlphaAnimation,或者如果我必须使用计时器系统在fBitmap上循环我想要随着时间推移淡出的红线。

任何想法?

编辑:好的,这是我一年后回到它后最终解决的问题:

我实现了一个SurfaceView,并创建了一个不断更新Canvas的线程。

@Override
public void run() {
    while (isRunning) {
        if (!surfaceHolder.getSurface().isValid()) {
            continue;
        }

        decreaseLineOpacity();
        drawLinesInvalid();

        /* Other things to draw*/

        Canvas canvas = surfaceHolder.lockCanvas();

        canvas.drawBitmap(fBitmap, centerPointWidth, centerPointHeight, null);
        // mBitmap is the middleground with the line that fades away.
        // and is bound to mCanvas for drawing
        canvas.drawBitmap(mBitmap, centerPointWidth, centerPointHeight, null);
        canvas.drawBitmap(iBitmap, centerPointWidth, centerPointHeight, null);

        surfaceHolder.unlockCanvasAndPost(canvas);
    }
}

然后是处理不透明度和绘制线条的方法,我将我在队列中绘制的每一条线存储起来,直到它达到0的不透明度,然后我将其删除所以只需要需要的线条动画留下:

    private void drawLinesInvalid() {
        Iterator<int[]> iterator = invalidLines.iterator();
        // Loop through each element in the Queue, delete it from the bitmap with the porter
        // duff mode to keep the transparancy of the layer. Then draw line with the given opacity
        while (iterator.hasNext()) {
            int[] invalidLine = iterator.next();
            float[] line = {invalidLine[1], invalidLine[2], invalidLine[3], invalidLine[4]};
            Xfermode originalXfermode = paint.getXfermode();
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            mCanvas.drawLines(line, paint);
            paint.setXfermode(originalXfermode);

            paint.setColor(Color.RED);
            paint.setAlpha(invalidLine[0]);

            mCanvas.drawLines(line, paint);

        }
    }

// Call this function in the onTouch method
    private void addLineToInvalidList(float[] line) {
        // Store each line a queue with its current opacity
        int[] lineWithOpacity = new int[5];
        lineWithOpacity[0] = 250;
        lineWithOpacity[1] = (int) line[0];
        lineWithOpacity[2] = (int) line[1];
        lineWithOpacity[3] = (int) line[2];
        lineWithOpacity[4] = (int) line[3];
        invalidLines.add(lineWithOpacity);
    }

    private void decreaseLineOpacity() {
        Iterator<int[]> iterator = invalidLines.iterator();
        // Remove all lines that are finished animating (opacity = 0)
        while (iterator.hasNext()) {
            int[] line = iterator.next();
            if (line[0] == 0) {
                iterator.remove();
            }
        }

        // Decrease opacity on lines that are left
        iterator = invalidLines.iterator();
        while (iterator.hasNext()) {
            int[] line = iterator.next();
            line[0] -= 10;
        }
    }

1 个答案:

答案 0 :(得分:1)

考虑到您在同一视图上绘制所有三个位图,使用AlphaAnimation可能有点棘手。

我建议生成一个线程,该线程会随着时间的推移改变无效红线位图的alpha值(使用Thread.sleep睡眠设置的间隔)。但是,要实现这一目标,您应该考虑使用SurfaceView,因为多次调用postInvalidate可能会非常昂贵(除非在Android 3.0+上运行硬件加速)。