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的使用在后面在是。
}
}
推荐阅读
- android第三方框架(五)ButterKnife
- Android中的AES加密-下
- 带有Hilt的Android上的依赖注入
- android|android studio中ndk的使用
- Android事件传递源码分析
- RxJava|RxJava 在Android项目中的使用(一)
- Android7.0|Android7.0 第三方应用无法访问私有库
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- android防止连续点击的简单实现(kotlin)
- Android|Android install 多个设备时指定设备