Очистка холста с помощью Canvas.drawColor()

я пытаюсь изменить фоновое изображение пользовательского представления с некоторым успехом. изображение изменится, но проблема в том, что я все еще вижу следы старого изображения. когда я пытаюсь очистить холст перед рисованием нового изображения, он не работает. я создаю растровое изображение для хранения изображения. при изменении изображения я вызываю Canvas.drawColor() перед рисованием нового изображения, но старое изображение сохраняется. я пробовал drawColor(0), drawColor(Color.BLACK), c.drawColor(0, PorterDuff.Mode.CLEAR), и ничего из вышеперечисленного не работает. поэтому я должен был опубликовать это для обзора более опытных умов, чем мой.

фактический код выглядит следующим образом:

private int bgnd;
private boolean switching;

public void setBgnd(int incoming){
    switching = true;
    switch (incoming){

    case R.drawable.image1:
        bgnd = incoming;
        this.invalidate();
        break;

    case R.drawable.image2:
        bgnd = incoming;
        this.invalidate();
        break;

    }
}



protected void onDraw(Canvas c){
    if(switching == true){
        Bitmap b = BitmapFactory.decodeResource(getResources(), bgnd);
        c.drawColor(0, PorterDuff.Mode.CLEAR);
        c.drawBitmap(b, 0, 0, null);
        switching = false;

    }else{
        Bitmap b = BitmapFactory.decodeResource(getResources(), bgnd);
        c.drawBitmap(b, 0, 0, null);
    }
}

person Prmths    schedule 10.01.2011    source источник


Ответы (4)


Как и вы, я изо всех сил пытался очистить верхний слой/поверхность в моем многослойном/поверхностном приложении. После 2 дней поиска и кодирования я нашел свой собственный способ, и вот как я очистил холст перед рисованием, вы можете использовать его при наличии нескольких слоев/видов поверхности. Фоновый слой не будет закрашен черным, в этом вся хитрость.

Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
canvas.drawPaint(paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC));
// start your own drawing
person longdooooo    schedule 09.08.2011
comment
Я думаю, что мне потребовалось бы более 2 дней, чтобы понять это, по сравнению с 2 минутами, которые потребовались мне, чтобы добраться сюда. Спасибо, странныйInAStrangerLand + longdooooo - person Mark Lapasa; 26.01.2012

Вы можете использовать метод Canvas drawRGB.

person ojs    schedule 10.12.2011
comment
drawRGB() не очищает альфа-канал, и растровое изображение становится непрозрачным, поэтому его можно использовать, только если растровое изображение является единственным слоем или фоновым слоем. Также есть метод drawARGB(), который также позволяет обрабатывать альфа-канал. Хотя не пробовал, работает ли. - person Oliver Hausler; 25.11.2014
comment
Обратите внимание, что drawRGB использует только drawColor(Color.rgb(r, g, b)) - person TameHog; 10.04.2015

Вам не нужно также вызывать invalidate() из вашего метода onDraw, чтобы изменения, сделанные в этом onDraw, обновлялись на экране?

Инвалидация () в вашем переключателе вызовет ваш onDraw после того, как вы вызовете setBgnd, но ничего не говорит о перерисовке после того, как вы внесли изменения в Canvas.

person C0deAttack    schedule 10.01.2011
comment
у меня сложилось впечатление, что вызов invalidate() сообщит представлению о вызове onDraw() и нарисует себя. в этом случае размещение этого вызова в методе приведет к тому, что он зациклится навсегда, как показано в примере по адресу: anddev.org/basic_and_simple_2d_drawing_-_animation-t3085.html - person Prmths; 10.01.2011
comment
Ах, вы правы, пришлось поискать, developer.android.com /guide/topics/graphics/index.html. Извините, мое понимание было неверным. - person C0deAttack; 10.01.2011
comment
Я тоже так думал в начале. У меня возникает вопрос: если invalidate() сообщает представлению о перерисовке себя, почему это представление не перерисовывается полностью, пока оно не будет перемещено позже в анимации? нижняя половина объекта выглядит правильно, но другая половина по-прежнему остается старой поверхностью. - person Prmths; 12.01.2011
comment
Я также пытался использовать 8-битное изображение, так как читал, что проблема может быть вызвана трудностями, с которыми Android сталкивается с 32-битными изображениями. Я не думал, что это так, и я обнаружил, что это бесполезно. я также пробовал setBackgroundResource() (на самом деле то, что я пробовал первым, даже до того, как возился с холстом), но он также не работает, даже когда вызывается изнутри onDraw(). - person Prmths; 13.01.2011

Я просто встречаюсь с этой проблемой.

Я решаю это, повторяя «..Drawxxx();Post();» по крайней мере 3 раза, это работает хорошо.

Я предполагаю, что причиной является «двойная буферизация», иногда это «тройная буферизация». Нам нужно повторить наш рисунок, чтобы убедиться, что каждый «буфер» обновлен.

person ohzso    schedule 23.08.2018