Android - 用于 onDraw 的预绘制 Canvas

标签 android android-canvas android-ui

我过去常常使用 onDraw 方法在 ImageView 中进行绘图。 但是,我了解到最好在 onDraw 之外绘制 Canvas 并在 onDraw 中更新 Canvas 。

我知道这显然是错误的(因为它不起作用)但是我将如何完成我正在尝试做的事情:

@Override 
public void onDraw(Canvas c) {
  c = this.newCanvas;
  super.onDraw(c);
}

最佳答案

    public class GameLoopThread extends Thread {
private GameView view;
private boolean running = false;

public GameLoopThread(GameView view) {
      this.view = view;
}

public void setRunning(boolean run) {
      running = run;
}

@Override
public void run() {

      while (running) {
             Canvas c = null;

             try {
                    c = view.getHolder().lockCanvas();
                    synchronized (view.getHolder()) {
                        if (c != null) {
                            view.onDraw(c);
                        }

                    }
             } finally {
                    if (c != null) {
                           view.getHolder().unlockCanvasAndPost(c);
                    }
             }

             try {

                           sleep(10);
             } catch (Exception e) {}
      }
}
}

创建那个线程然后在你的 Activity 中做这样的事情

    @Override
public void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);
    super.onCreate(savedInstanceState);
    setContentView(new GameView(GameActivity.this));
}

然后在 GameViewClass 中做这样的事情

   public class GameView extends SurfaceView {

   private SurfaceHolder holder;
   private GameLoopThread gameLoopThread;


   public GameView(Context context) {
         super(context);
         gameLoopThread = new GameLoopThread(this);
         holder = getHolder();
         holder.addCallback(new SurfaceHolder.Callback() {

                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {
                       boolean retry = true;
                       gameLoopThread.setRunning(false);
                       while (retry) {
                              try {
                                    gameLoopThread.join();
                                    retry = false;
                              } catch (InterruptedException e) {
                              }
                       }
                }

                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                       gameLoopThread.setRunning(true);
                       gameLoopThread.start();
                }

                @Override
                public void surfaceChanged(SurfaceHolder holder, int format,
                              int width, int height) {
                }
         });

   }

   @Override
   protected void onDraw(Canvas canvas) {
         //Do Drawing
   }
}

这里重要的是线程手动自动重复调用 onDraw() 方法,并且您正在锁定 Canvas ,在其上绘图,然后将其发布。如果你不需要超快的刷新率,那么你最好做这样的事情:

    @Override 
    public void onDraw(Canvas c) {
        c = this.getHolder().lockCanvas();
        if (c != null) {
           //draw on canvas
        }
        if (c != null) {
            this.getHolder().unlockCanvasAndPost(c);
        }
    }

我只是不知道最后一点是否有效,从未测试过。 另外,如果你想在 on draw 方法之外进行绘图,你可以在一个线程中运行你的更新(在你的 Canvas 上绘图),并且每次调用 onDraw 方法时让它检查 Canvas 是否准备好邮政。例如,让你的线程有一个 bool 值,一旦 Canvas 被拉出它就被设置为 false,所以线程会为你绘制一个新的,但是一旦完成绘制就将 bool 值设置为 true。在 ondraw 方法中检查 bool 值是否为真以及是否拉 Canvas 。

关于Android - 用于 onDraw 的预绘制 Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11917554/

相关文章:

Android 是否可以在 XML 文件中定义 map ?

java - 以一定角度在 Canvas 上绘制文本

android - 关于android中的lineargradient

android - 样式 Android SearchView 下拉弹出窗口

android - 如何更改主题中的 textColorPrimary?

没有 CarModeEnabled 的 Android 夜间模式

android - 使用带 Fragment 的 DrawerLayout 时设置 ListView 的 LayoutParams

java - 在 Android 中通过 SSL 使用 WCF 服务

android - 谷歌分析跟踪器

android - Galaxy Nexus 上的 Canvas Clip 功能错误