android|android canvas

canvas 理解 辅助坐标系,辅助绘制
1

//剪切canvas,canvas本身位置不变,剩下的是截切内的区域,Rect是相对与整个屏幕的,而canvas是他剩余的不分并且位置不变(不回到左上角0点位置) canvas.clipRect(new Rect(300, 300, 600, 600)); //canvas平移 canvas.translate(-400,-400); //剪切canvas,在canvas上面剪切的剩余不分和Rect取交集 canvas.clipRect(new Rect(0, 0, 700, 700));

2
canvas.save(); //将当前的画布状态压入栈,会面可以取出这个栈来canvas canvas.restore(); //弹出一个画布栈返回上一个栈的canvas状态,来canvas

canvas的两种操作
1,canvas位置(大小、位置)、matrix操作(translate scale rotate skew) 剪切操作clipX
2,canvas绘制 drawX
【android|android canvas】canvas.save()、canvas.saveLayer(),可以设置matrix操作(MATRIX_SAVE_FLAG )或者剪切操作(CLIP_SAVE_FLAG) 的状态来确定canvas.restore()恢复的是那种canvas.
MATRIX_SAVE_FLAG 操作translate scale rotate skew
测试代码
public static class SampleView extends View { private Paint mPaint; private Path mPath = new Path(); private float mPreX,mPreY; private int mItemWaveLength = 800; private int dx; public SampleView(Context context) { super(context); init(); }public SampleView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); }public SampleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); }public SampleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); }public void init(){ setFocusable(true); mPaint = new Paint(); mPaint.setAntiAlias(true); startAnim(); }@Override public boolean onTouchEvent(MotionEvent event) { //普通手势 //switch (event.getAction()){ //case MotionEvent.ACTION_DOWN: { //mPath.moveTo(event.getX(), event.getY()); //return true; //} //case MotionEvent.ACTION_MOVE: //mPath.lineTo(event.getX(), event.getY()); //postInvalidate(); //break; //default: //break; //} //贝塞尔手势 //switch (event.getAction()){ //case MotionEvent.ACTION_DOWN:{ //mPath.moveTo(event.getX(),event.getY()); //mPreX = event.getX(); //mPreY = event.getY(); //return true; //} //case MotionEvent.ACTION_MOVE:{ //float endX = (mPreX+event.getX())/2; //float endY = (mPreY+event.getY())/2; //mPath.quadTo(mPreX,mPreY,endX,endY); //mPreX = event.getX(); //mPreY =event.getY(); //invalidate(); //} //break; //default: //break; //} return super.onTouchEvent(event); }@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); wave(canvas); //bsrDraw(canvas); //bsrTest(canvas); //test2(canvas); //test1(canvas); //canvas.drawColor(Color.WHITE); //canvas.translate(10, 10); //mPaint.setColor(Color.RED); //canvas.drawCircle(75, 75, 75, mPaint); //canvas.saveLayerAlpha(0, 0, 200, 200, 0x88, LAYER_FLAGS); //mPaint.setColor(Color.BLUE); //canvas.drawCircle(125, 125, 75, mPaint); //canvas.restore(); } public void startAnim(){ ValueAnimator animator = ValueAnimator.ofInt(0,mItemWaveLength); animator.setDuration(2000); animator.setRepeatCount(ValueAnimator.INFINITE); animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { dx = (int)animation.getAnimatedValue(); postInvalidate(); } }); animator.start(); }private void wave(Canvas canvas) { mPath.reset(); int originY = 300; int halfWaveLen = mItemWaveLength/2; mPath.moveTo(-mItemWaveLength+dx,originY); for (int i = -mItemWaveLength; i<=getWidth()+mItemWaveLength; i+=mItemWaveLength){ mPath.rQuadTo(halfWaveLen/2,-100,halfWaveLen,0); mPath.rQuadTo(halfWaveLen/2,100,halfWaveLen,0); } mPath.lineTo(getWidth(),getHeight()); mPath.lineTo(0,getHeight()); mPath.close(); canvas.drawPath(mPath,mPaint); }private void bsrDraw(Canvas canvas) { Paint paint = new Paint(); paint.setColor(Color.GREEN); paint.setStyle(Paint.Style.STROKE); canvas.drawPath(mPath,paint); }private void bsrTest(Canvas canvas) { Paint paint = new Paint(); paint.setStyle(Paint.Style.STROKE); paint.setColor(Color.GREEN); Path path = new Path(); path.moveTo(100,300); path.quadTo(200,200,300,300); path.quadTo(400,400,500,300); canvas.drawPath(path,paint); }private void test2(Canvas canvas) { int paddingLeft = getPaddingLeft(); int paddingTop = getPaddingTop(); canvas.drawColor(Color.BLACK); Paint paint = new Paint(); paint.setColor((Color.RED)); canvas.drawRect(new Rect( paddingLeft, paddingTop, getWidth() - paddingLeft, getHeight() - paddingTop),paint); //保存的画布大小为全屏幕大小 canvas.save(); canvas.clipRect(new Rect(100 + paddingLeft, 100 +paddingTop, 800, 800)); canvas.drawColor(Color.GREEN); //保存画布大小为Rect(100, 100, 800, 800) canvas.save(); canvas.clipRect(new Rect(200 + paddingLeft, 200 +paddingTop, 700, 700)); canvas.drawColor(Color.BLUE); //保存画布大小为Rect(200, 200, 700, 700) canvas.save(); //剪切canvas,canvas本身位置不变,剩下的是截切内的区域,Rect是相对与整个屏幕的,而canvas是他剩余的不分并且位置不变(不回到左上角0点位置) canvas.clipRect(new Rect(300 + paddingLeft, 300 +paddingTop, 600, 600)); //canvas平移 canvas.translate(-400,-400); //剪切canvas,在canvas上面剪切的剩余不分和Rect取交集 //canvas.clipRect(new Rect(0 + paddingLeft, 0 +paddingTop, 700, 700)); //canvas.drawColor(Color.BLACK); //保存画布大小为Rect(300, 300, 600, 600) //canvas.save(); //将当前的画布状态压入栈,会面可以取出这个栈来canvas //canvas.restore(); //弹出一个画布栈返回上一个栈来canvastranslatescale rotate skew clipXXX drawXXXXX //canvas.clipRect(new Rect(400, 400, 500, 500)); //canvas.drawColor(Color.WHITE); // ////将栈顶的画布状态取出来,作为当前画布,并画成黄色背景 //canvas.restore(); //canvas.drawColor(Color.YELLOW); }private void test1(Canvas canvas) { canvas.translate(100, 100); canvas.drawColor(Color.RED); //可以看到,整个屏幕依然填充为红色 Paint paint = new Paint(); paint.setColor(Color.GREEN); canvas.drawRect(new Rect(-100, -100, 0, 0),paint); canvas.scale(0.5f, 0.5f); paint.setColor(Color.BLUE); canvas.drawRect(new Rect(0, 0, 100, 100), paint); //缩放了canvas.translate(200, 0); canvas.rotate(30); paint.setColor(Color.YELLOW); canvas.drawRect(new Rect(0, 0, 100, 100), paint); //旋转了canvas.translate(200, 0); canvas.skew(.5f, .5f); //扭曲了 paint.setColor(Color.BLACK); canvas.drawRect(new Rect(0, 0, 100, 100), paint); // canvas.setMatrix(matrix); //Matrix的使用在后面在是。 } }

    推荐阅读