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()
    }
}
相關文章
相關標籤/搜索