I'm trying to do simple painter. The problem that it looks like Android has three independent Canvas and give me it for drawing sequentially.
我正在努力做一个简单的画家。它看起来像Android有三个独立的Canvas的问题,并给我顺序绘制。
I made UI with SurfaceView
, took Holder from it.
我使用SurfaceView制作了UI,从中获取了Holder。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sv = (SurfaceView) findViewById(R.id.sv);
holder = sv.getHolder();
holder.addCallback(callback);
}
Then took Surface.
然后拿了Surface。
@Override
public void surfaceCreated(SurfaceHolder holder) {
surface = holder.getSurface();
}
And by events from OnTouchListener()
draw dots and lines.
通过OnTouchListener()的事件绘制点和线。
private void paintStartDot(float x, float y) {
Canvas canvas = surface.lockCanvas(null);
canvas.drawPoint(x, y, drawPaint);
surface.unlockCanvasAndPost(canvas);
lastX = x;
lastY = y;
}
private void paintEndDot(float x, float y) {
Canvas canvas = surface.lockCanvas(null);
canvas.drawLine(lastX, lastY, x, y, drawPaint);
surface.unlockCanvasAndPost(canvas);
lastX = x;
lastY = y;
}
The screencast:
截屏视频:
https://youtu.be/NNDnzrtMLZI
What is wrong?
哪里不对?
Full source is available here: https://github.com/tseglevskiy/canvasdemo1/blob/error/app/src/main/java/ru/jollydroid/canvasdemo1/MainActivity.java
完整资源来源:https://github.com/tseglevskiy/canvasdemo1/blob/error/app/src/main/java/ru/jollydroid/canvasdemo1/MainActivity.java
1 个解决方案
#1
5
The Canvas
that Surface.lockCanvas
gives you is not persistent. The moment you call unlockCanvasAndPost
, the contents of the surface buffer are pushed out to the screen. Every time you call lockCanvas
you need to redraw the picture from scratch.
Surface.lockCanvas为您提供的Canvas不是持久性的。调用unlockCanvasAndPost时,表面缓冲区的内容将被推送到屏幕。每次调用lockCanvas时,都需要从头开始重绘图片。
If you want to update the canvas incrementally, you should keep an "off-screen" canvas backed by a Bitmap
that you update in response to user actions. Then paint the bitmap to the Surface
canvas.
如果要以增量方式更新画布,则应保留一个“Bit-screen”画布,该画布由您为响应用户操作而更新的Bitmap支持。然后将位图绘制到Surface画布。
private void paintStartDot(float x, float y) {
if (mBitmap == null) return; // not ready yet
Canvas canvas = new Canvas(mBitmap);
canvas.drawPoint(x, y, drawPaint);
// draw the bitmap to surface
canvas = surface.lockCanvas(null);
canvas.drawBitmap(mBitmap, 0, 0, null);
surface.unlockCanvasAndPost(canvas);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// good place to create the Bitmap
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config. ARGB_8888);
// also here we need to transform the old bitmap to new one
}
I'm not sure if you really need a SurfaceView
. You could just extend the View
and override its View.onDraw
method. In that case, call view.invalidate()
to indicate it needs to be redrawn.
我不确定你是否真的需要SurfaceView。您可以只扩展View并覆盖其View.onDraw方法。在这种情况下,请调用view.invalidate()以指示需要重绘。
See also: Android View.onDraw() always has a clean Canvas
另请参阅:Android View.onDraw()始终具有干净的Canvas
#1
5
The Canvas
that Surface.lockCanvas
gives you is not persistent. The moment you call unlockCanvasAndPost
, the contents of the surface buffer are pushed out to the screen. Every time you call lockCanvas
you need to redraw the picture from scratch.
Surface.lockCanvas为您提供的Canvas不是持久性的。调用unlockCanvasAndPost时,表面缓冲区的内容将被推送到屏幕。每次调用lockCanvas时,都需要从头开始重绘图片。
If you want to update the canvas incrementally, you should keep an "off-screen" canvas backed by a Bitmap
that you update in response to user actions. Then paint the bitmap to the Surface
canvas.
如果要以增量方式更新画布,则应保留一个“Bit-screen”画布,该画布由您为响应用户操作而更新的Bitmap支持。然后将位图绘制到Surface画布。
private void paintStartDot(float x, float y) {
if (mBitmap == null) return; // not ready yet
Canvas canvas = new Canvas(mBitmap);
canvas.drawPoint(x, y, drawPaint);
// draw the bitmap to surface
canvas = surface.lockCanvas(null);
canvas.drawBitmap(mBitmap, 0, 0, null);
surface.unlockCanvasAndPost(canvas);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// good place to create the Bitmap
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config. ARGB_8888);
// also here we need to transform the old bitmap to new one
}
I'm not sure if you really need a SurfaceView
. You could just extend the View
and override its View.onDraw
method. In that case, call view.invalidate()
to indicate it needs to be redrawn.
我不确定你是否真的需要SurfaceView。您可以只扩展View并覆盖其View.onDraw方法。在这种情况下,请调用view.invalidate()以指示需要重绘。
See also: Android View.onDraw() always has a clean Canvas
另请参阅:Android View.onDraw()始终具有干净的Canvas