Android-SurfaceView与SurfaceHolder对象

  一、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()
    }
}
相关文章
相关标签/搜索