Android,canvas:如何清除(删除内容)一个canvas(=位图),生活在一个surfaceView?
为了制作一个简单的游戏,我使用了一个模板来绘制一个像这样的位图的canvas:
private void doDraw(Canvas canvas) { for (int i=0;i<8;i++) for (int j=0;j<9;j++) for (int k=0;k<7;k++) { canvas.drawBitmap(mBits[allBits[i][j][k]], i*50 -k*7, j*50 -k*7, null); } }
(canvas在“run()”中定义/ SurfaceView存在于GameThread中。)
我的第一个问题是如何清除(或重绘) 整个canvas以获得新的布局?
其次,我怎样才能更新屏幕的一部分?
// This is the routine that calls "doDraw": public void run() { while (mRun) { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { if (mMode == STATE_RUNNING) updateGame(); doDraw(c); } } finally { if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } }
如何清除(或重新绘制)全屏布局(=在游戏中尝试)?
只需调用Canvas.drawColor(Color.BLACK)
,或者任何你想清除你的Canvas
颜色。
而且:我怎样才能更新屏幕的一部分?
没有更新“屏幕的一部分”的方法,因为Android操作系统在更新屏幕时正在重新绘制每个像素。 但是,当您不清除Canvas
的旧图时,旧图仍然在表面上,这可能是“更新屏幕的一部分”的一种方法。
所以,如果你想“更新屏幕的一部分”,只要避免调用Canvas.drawColor()
方法。
用PorterDuff清除模式绘制透明的颜色为我想要的做诀窍。
Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
发现这在谷歌组和这对我工作..
Paint clearPaint = new Paint(); clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); canvas.drawRect(0, 0, width, height, clearPaint);
这将删除绘图矩形等,同时保持设置位图。
我试了@mobistry的答案:
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
但它不适合我。
对我来说,解决scheme是:
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);
也许有人有同样的问题。
mBitmap.eraseColor(Color.TRANSPARENT); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
使用Path类的重置方法
Path.reset();
请将下面的代码粘贴到surfaceview扩展类的构造函数中………….
构造函数编码
SurfaceHolder holder = getHolder(); holder.addCallback(this); SurfaceView sur = (SurfaceView)findViewById(R.id.surfaceview); sur.setZOrderOnTop(true); // necessary holder = sur.getHolder(); holder.setFormat(PixelFormat.TRANSPARENT);
xml编码
<com.welcome.panelview.PanelViewWelcomeScreen android:id="@+id/one" android:layout_width="600px" android:layout_height="312px" android:layout_gravity="center" android:layout_marginTop="10px" android:background="@drawable/welcome" />
尝试上面的代码…
对于我来说,调用Canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)
或类似的东西只会在我触摸屏幕后才起作用。 所以我会打电话的上面的代码行,但屏幕只会清除后,然后触摸屏幕。 所以对我来说,工作是调用invalidate()
然后调用创build时调用的init()
来初始化视图。
private void init() { setFocusable(true); setFocusableInTouchMode(true); setOnTouchListener(this); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(6); mCanvas = new Canvas(); mPaths = new LinkedList<>(); addNewPath(); }
这是一个最小例子的代码,显示你总是必须在每一帧重绘Canvas的每个像素。
此活动在SurfaceView上每秒绘制一个新的位图,而不清除之前的屏幕。 如果您testing它,您会看到位图并不总是写入相同的缓冲区,屏幕将在两个缓冲区之间交替。
我testing了我的手机(Nexus S,Android 2.3.3)和仿真器(Android 2.2)。
public class TestCanvas extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new TestView(this)); } } class TestView extends SurfaceView implements SurfaceHolder.Callback { private TestThread mThread; private int mWidth; private int mHeight; private Bitmap mBitmap; private SurfaceHolder mSurfaceHolder; public TestView(Context context) { super(context); mThread = new TestThread(); mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon); mSurfaceHolder = getHolder(); mSurfaceHolder.addCallback(this); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mWidth = width; mHeight = height; mThread.start(); } @Override public void surfaceCreated(SurfaceHolder holder) {/* Do nothing */} @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mThread != null && mThread.isAlive()) mThread.interrupt(); } class TestThread extends Thread { @Override public void run() { while (!isInterrupted()) { Canvas c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { c.drawBitmap(mBitmap, (int) (Math.random() * mWidth), (int) (Math.random() * mHeight), null); } } finally { if (c != null) mSurfaceHolder.unlockCanvasAndPost(c); } try { sleep(1000); } catch (InterruptedException e) { interrupt(); } } } } }
canvas.drawColor(Color.TRANSPARENT, Mode.MULTIPLY);
你的第一个要求,如何清除或重绘整个canvas – 回答 – 使用canvas.drawColor(color.Black)方法用黑色或任何你指定的颜色清除屏幕。
你的第二个要求,如何更新屏幕的一部分 – 回答 – 例如,如果你想保持屏幕上的所有其他东西不变,但在屏幕的一个小区域显示一个整数(说计数器),每五秒钟后增加。 然后使用canvas.drawrect方法通过指定左上angular和底部绘制该小区域并绘制。 然后计算你的计数器值(使用postdalayed 5秒钟等,如Handler.postDelayed(Runnable_Object,5000);),将其转换为文本string,计算这个小矩形的x和y坐标,并使用文本视图来显示变化计数器值。
打电话
canvas.drawColor(Color.TRANSPARENT)