何为脏矩形?比如surfaceview上绘制旋转图片的时候,只刷新一个特定的矩形区域就可以了。这个矩形区域就是脏矩形。在surfaceview上 canvas = holder.lockCanvas(new Rect(0, 0, 130, 130)); //获取画布 像这种带rect参数的就是脏矩形的刷新。

    请看源码:

    1. package yan.guoqi.rectphoto;
    2. import android.content.Context;
    3. import android.graphics.Bitmap;
    4. import android.graphics.BitmapFactory;
    5. import android.graphics.Canvas;
    6. import android.graphics.Matrix;
    7. import android.graphics.Paint;
    8. import android.graphics.PixelFormat;
    9. import android.graphics.Rect;
    10. import android.util.AttributeSet;
    11. import android.util.Log;
    12. import android.view.SurfaceHolder;
    13. import android.view.SurfaceView;
    14. public class DrawSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
    15. private static final String tag2 = "DrawSV";
    16. private boolean runFlag = true;
    17. protected SurfaceHolder holder;
    18. private Bitmap rotateImg;
    19. private Thread myThread;
    20. public DrawSurfaceView(Context context, AttributeSet attrs)
    21. //构造函数
    22. {
    23. super(context, attrs);
    24. // TODO Auto-generated constructor stub
    25. rotateImg = BitmapFactory.decodeResource(getResources(), R.drawable.rotate_circle);
    26. rotateImg = Bitmap.createScaledBitmap(rotateImg, 100, 100, true);
    27. holder = this.getHolder();
    28. holder.addCallback(this);
    29. holder.setFormat(PixelFormat.TRANSPARENT); //顶层绘制SurfaceView设成透明
    30. this.setZOrderOnTop(true);
    31. myThread = new Thread(new MyThread());
    32. }
    33. public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
    34. // TODO Auto-generated method stub
    35. Log.v(tag2, "DrawSV:surfaceChanged...");
    36. }
    37. public void surfaceCreated(SurfaceHolder arg0) {
    38. // TODO Auto-generated method stub
    39. Log.v(tag2, "DrawSV:surfaceCreated...");
    40. //启动自定义线程
    41. myThread.start();
    42. }
    43. public void surfaceDestroyed(SurfaceHolder arg0) {
    44. // TODO Auto-generated method stub
    45. Log.v(tag2, "DrawSV:surfaceDestroyed...");
    46. //终止自定义线程
    47. runFlag = false;
    48. myThread.interrupt();
    49. }
    50. /*自定义线程*/
    51. class MyThread implements Runnable{
    52. public void run() {
    53. // TODO Auto-generated method stub
    54. Canvas canvas = null;
    55. int rotate = 0;
    56. while(runFlag){
    57. try {
    58. canvas = holder.lockCanvas(new Rect(0, 0, 130, 130)); //获取画布
    59. Paint paint = new Paint();
    60. //canvas.drawBitmap(rotateImg, 0, 0, paint); //绘制旋转的背景
    61. //创建矩阵控制图片旋转和平移
    62. Matrix matrix = new Matrix();
    63. //设置旋转角度
    64. matrix.postRotate((rotate += 48) % 360,
    65. rotateImg.getWidth() / 2, rotateImg.getHeight() / 2);
    66. //设置左边距和上边距
    67. matrix.postTranslate(0, 0);
    68. //绘制旋转图片
    69. canvas.drawBitmap(rotateImg, matrix, paint);
    70. //休眠控制最大帧率为每秒3绘制30次
    71. Thread.sleep(30);
    72. holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像
    73. } catch (Exception e) {
    74. // TODO: handle exception
    75. Log.v(tag2, "DrawSurfaceView:绘制失败...");
    76. }
    77. }
    78. }
    79. }
    80. }
    81.  

    需要注意的几点:

    第一,就是如何安全中止一个线程。这里通过设置标志位来实现。因为自带的stop()方法不安全,android本身都不推荐。关于如何安全中止线程可以参考这里:http://www.iteye.com/problems/67052 http://www.dewen.org/q/1957

    第二,holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像 这句话必须和 canvas = holder.lockCanvas(new Rect(0, 0, 130, 130)); //获取画布 在一个{ }里。像这里的http://www.cnblogs.com/jqyp/archive/2012/01/01/2309692.html的做法在程序退出时会抛出异常。原因是线程中止的时候无法再解锁画布了。

    第三,利用Matrix让图片旋转的核心代码:

    1. //创建矩阵控制图片旋转和平移
    2. Matrix matrix = new Matrix();
    3. //设置旋转角度
    4. matrix.postRotate((rotate += 48) % 360,
    5. rotateImg.getWidth() / 2, rotateImg.getHeight() / 2);
    6. //设置左边距和上边距
    7. matrix.postTranslate(0, 0);
    8. //绘制旋转图片
    9. canvas.drawBitmap(rotateImg, matrix, paint);
    10. //休眠控制最大帧率为每秒3绘制30次
    11. Thread.sleep(30);

    第四,之所以将此surfaceview设成顶层透明,原因是杂家想探索在底层surfaceview预览摄像头视频的时候,在顶层的surfaceview绘制一个旋转的图片动画。但遗憾的是,图片确实是旋转了,底层的摄像头预览也正常。但就是旋转的图片将预览画面挡住了。唉,看来前文http://blog.csdn.net/yanzi1225627/article/details/8580034这里的360扫描二维码的界面不是通过这种思路实现的,抑或是 我旋转的图片不是透明的??? **