一、Android-SurfaceView与SurfaceHolder对象:html
http://blog.csdn.net/andyhuabing/article/details/7657069 java
二、Android学习之 VideoView,SurfaceView:android
http://blog.csdn.net/abidepan/article/details/8679837canvas
三、一个简单的demo引起的深层次思索:ide
http://bbs.csdn.net/topics/390834677函数
-- 双缓冲理解 : http://www.apkbus.com/android-99309-1-1.html 分析SurfaceView源码
-- 双缓冲与单缓冲区别 : http://blog.csdn.net/lcfeng1982/article/details/7431446
-- 双缓冲与但缓冲动画绘制区别demo : http://blog.csdn.net/geolo/article/details/6024761学习
四、Android 双缓冲测试
所谓双缓冲技术其实很简单:当程序须要在指定View上进行绘制时,程序并不直接绘制到该View组件上,而是先绘制到内存中的一个Bitmap图片(这就是缓冲区)上,等到内存中的Bitmap绘制好以后,再一次性地将Bitmap绘制到View组件上。动画
实现思路:spa
1).定义一个内存中图片,将他做为缓冲区Bitmap cacheBitmap = null;
2).定义缓冲区Cache的Canvas对象 Canvas cacheCanvas = null;
3).设置cacheCanvas将会绘制到内存的bitmap上。 cacheCanvas.setBitmap(cacheBitmap);
4). 将cacheBitmap绘制到该View上.。canvas.drawBitmap(cacheBitmap,0,0,p);
class DrawView extends View { float preX; float preY; private Path path; public Paint paint = null; final int VIEW_WIDTH = 900; final int VIEW_HEIGHT = 1024; //定义一个内存中的图片, 该图片将做为缓冲区 Bitmap cacheBitmap = null; //定义cacheBitmap上的Canvas对象 Canvas cacheCanvas = null; public DrawView(Context context, AttributeSet set){ super(context, set); //建立一个与该view相同大小的缓冲区 cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH, VIEW_HEIGHT, Bitmap.Config.ARGB_8888); cacheCanvas = new Canvas(); path = new Path(); //设置cacheCanvas将会绘制到内存中的cacheBitmap上 cacheCanvas.setBitmap(cacheBitmap); paint = new Paint(Paint.DITHER_FLAG); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(1); paint.setAntiAlias(true); paint.setDither(true); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: path.moveTo(x, y); preX = x; preY = y; break; case MotionEvent.ACTION_MOVE: path.quadTo(preX, preY, x, y); preX = x ; preY = y; break; case MotionEvent.ACTION_UP: cacheCanvas.drawPath(path, paint); path.reset(); break; } // Log.i("ysong", "调用了invalidate()函数"); invalidate(); return true; } @Override protected void onDraw(Canvas canvas) { Paint bmpPaint = new Paint(); //将cacheBitmap绘制到该View组件上 canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint); //沿着path绘制 canvas.drawPath(path, paint); //为何还要绘制一次path??? //这行代码很是重要, //每次手指在屏幕上面移动,path会将轨迹记录下来,而后绘制到缓冲的bitmap上面 // view 每次调用invalidate()更新的时候,会将bitmap上面缓冲的内容绘制到view上面(也就是canvas) // ACTION_MOVE 和 ACTION_DOWN 也会触发invalid()更新view,这个时候path的内容尚未绘制到cacheBitmap上面, // 若是没有上面这行canvas.drawPath(path, paint), 效果就会是当手指离开屏幕时,以前绘制的轨迹才会出现,感受像是慢了半拍 // 有了上面这一行代码,当ACTION_MOVE手指移动的时候,就会把临时的path绘制到view上面,这样感受像是画笔随着手指在动 // 最后再把cacheBitmap的内容绘制到view上面 //ACTION_MOVE 其实并非从手指DOWN到UP的过程,其中会触发不少次invalid()函数, // ACTION_MOVE其实包含了两个动做,只不是期间的时间间隔很是短, 看起来感受像是一个动做, 能够经过log来测试一下,看一下移动调用了多少次invalidate() } }