Android Canvas: сделать потертую нарисованную линию / alphaAnimation на ощупь - PullRequest
0 голосов
/ 25 октября 2011

У меня есть 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 Ответ

1 голос
/ 25 октября 2011

Учитывая, что вы рисуете все три растровые изображения в одном и том же виде, использование AlphaAnimation может быть немного сложным.

Я бы предложил порождать поток, который изменяет альфа-значение недопустимой красной линии (s).) растровое изображение с течением времени (спит в течение установленных интервалов с Thread.sleep).Однако для того, чтобы это работало хорошо, вы должны использовать SurfaceView, так как вызов postInvalidate несколько раз может быть довольно дорогостоящим (если только он не работает на Android 3.0+ с аппаратным ускорением).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...