SurfaceView, onDraw и postInvalidate () что-то не так - PullRequest
1 голос
/ 25 марта 2012

Приложение ведет себя странно.У меня есть класс, расширяющий SurfaceView и реализующий SurfaceHolder.Callback.
Я пробовал 3 варианта кода, и только один работает так, как мне нужно (но я сомневаюсь, что это правильное решение), а другие ведут себя по-разному.
Итак, мой вопрос: почему и что не так, и если «правильное» решение неверно, так почему оно работает ...

Правильно для всех:

  1. Я пытался setWillNotDraw(boolean flag) flag (true / false)
  2. В наборе манифестов android:changeConfiguration="orientation"
  3. В основном макете установить фон с мозаичным изображением, определенным с помощью ресурсов XML.

Теперь "правильная реализация: у меня есть поток, который вызывает postInvalidate(); с задержками и вызовами между lockCanvas и unlockCanvas:
мой onDraw () и draw (Canvas c, int deg) одинаковы во всех вариантах:

@Override
public void onDraw(Canvas c) {
    draw(c,lastHeading);
    super.onDraw(c);
}

public synchronized void draw(Canvas c,int degrees) {
    Paint p=new Paint();
    p.setAntiAlias(true);
    c.save();

    rotateLayer(degrees,layer1, cLayers.getDrawable(0),false);
    rotateLayer(lastSideAngle, layer2, sLayers.getDrawable(1),true);
    rotateLayer(lastFrontAngle, layer2, fLayers.getDrawable(1),true);

    c.drawBitmap(layer1,0, 0, p);
    c.drawBitmap(layer2,0, 0, p);
    c.drawBitmap(layer3, 0,0, p);   
    c.restore();
}

Вариант кода проблемы A (и «правильный»):

@Override
public void run() {
    Canvas c=null;
    try
    {
        c=holder.lockCanvas(null);
        synchronized (holder) {
        postInvalidate();
    }
    finally
    {
        if(c!=null)
        holder.unlockCanvasAndPost(c);
    }
}

, почему он работает без проблем, однако тот же самый код без блокировки / разблокировки холста не работал в принципе?

Со следующей реализацией приложение работает хорошо, пока телефон не изменит ориентацию.При изменении ориентации требуется много времени, чтобы перерисовать поверхность, но при следующем изменении ориентации она быстро меняется.но в обоих вариантах я вызываю postInvalidate (), и я не понимаю, как блокировка / разблокировка холста влияет на postInvalidate ()?

@Override
public void run() {
    postInvalidate();
}

И в этом варианте я вижу на экране замороженное изображение, которое никогдаcannges:

@Override
public void run() {
    Canvas c=null;
    try
    {
        c=holder.lockCanvas(null);
        synchronized (holder) {
        draw(c,deg);
        //OR
        //onDraw(c)
    }
    finally
    {
        if(c!=null)
        holder.unlockCanvasAndPost(c);
    }
}

Есть еще один вариант, когда приложение рисует все растровые изображения, но фон накладывается на все.Так что я делаю неправильно и что мне нужно делать?

1 Ответ

0 голосов
/ 25 января 2015

Здесь:

@Override
public void run() {
Canvas c=null;
   try
   {
       c=holder.lockCanvas(null);
       synchronized (holder) {
       draw(c,deg);
       //OR
       //onDraw(c)
   }
   finally
   {
       if(c!=null)
       holder.unlockCanvasAndPost(c);
   } 
}

Вам необходимо настроить цикл, потому что в противном случае вы вызываете метод onDraw () только один раз.Это создаст непрерывную перерисовку:

while(true) {
   try
   {
       c=holder.lockCanvas(null);
       synchronized (holder) {
       draw(c,deg);
       //OR
       //onDraw(c)
   }
   finally
   {
       if(c!=null)
       holder.unlockCanvasAndPost(c);
   } 
}

Источник

...