android-canvas 之save与restore

很多资料中指出,canvas其实就是一个 画布,我们呢,用它给的各种工具(API)
在加上一支神奇的画笔(Paint类)可以在画布上画出各种形状。有两个关键的点,其一是画控件画布区域。(你画画必须画在纸上啊)其二就是 画控件的实际区域,电脑必定 智商超低,它不知道什么是画布,这对它来讲太高深,它觉得,你就直接告诉 在哪画? 这样的画就出现了坐标系,电脑只在坐标轴的正x和正y范围内进行绘制(大家注意我这说的电脑只在+与+y范围内不要误会了,如果是你自己手工绘制你可以在-x或者-y范围内绘制,只要范围内有画布即可)然而电脑可不管 画布在这区域内有没有!如果它画的范围内没有画布  那么它就画不上。即使他画了我们也看不到,画布必须在坐标的合理范围内,这样画布才能被画上画。


由于电脑绘制时候只认系统坐标(初始化的系统坐标的原点应该在屏幕的左上角,如下图所示)

a

然后你可以改变坐标系的位置,然后明确告诉电脑在哪个位置(坐标)上开始绘制。
save 的作用是保存canvas状态,实际上保存就是 坐标系的原点的位置和x 轴与y轴的延伸方向(因为你可以改变坐标的位置嘛!),这也是我们在下面那个例子中看到的。当你进行 平移,旋转,拉伸等操作时候 实际上 是对整个坐标系进行的上述操作。比如你在(30,40)的位置上画上一个点,然后旋转45度,这样(30, 40)的位置变了,因为坐标系的位置变了。如果你想 念save之前的坐标位置,只需要 调用 restore() 方法 把 那个坐标系从栈中取出。 你再绘图就是根据 save之前的坐标的位置进行绘画。

如下一个例子 就是对上述的合理解释的验证,代码有注释,我是继承了TextView类扩展的MyTextView类。

布局文件mytextview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <com.example.draw.MyTextView 
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:text="今晚吃班饭"/>
    <com.example.draw.MyTextView 
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:text="今晚吃班饭"/>
</LinearLayout>

onDraw里面的代码

protected void onDraw(Canvas canvas) {
        
        int height = getMeasuredHeight();//得到画布区域的高
        int width = getMeasuredWidth();//得到画布区域的宽
        
        int px = width / 2;
        int py = height / 2;
        
        Paint p1 = new Paint(Paint.ANTI_ALIAS_FLAG);
        p1.setColor(Color.RED);
        //给出画布区域(红色部分)
        canvas.drawRect(0,0, width,height,p1);
        //确定200,200的位置
        //因为我们给出控件在父控件中的大小为200dp,200dp
        //因此 控件的中心位置就是(200,200)高和宽都为400
        p1.setColor(Color.YELLOW);//黄色的圈
        canvas.drawCircle(200,200,20,  p1);
        
        p1.setColor(Color.BLACK);
        p1.setStrokeWidth(10);
        p1.setStyle(Paint.Style.FILL_AND_STROKE);
        
        //画出当前原点的位置
        canvas.drawCircle(0, 0, 20, p1);
        canvas.drawLine(0, 0, 0, 1000, p1);
        canvas.drawLine(0, 0, 1000, 0, p1);
        
        canvas.save();//保存上述坐标系的状态,放入
        canvas.translate(100, 300);//将坐标轴向右(dx)移动100 向下(dy)移动300
        
        //再次画出原点位置,并且画出x轴与y轴
        p1.setColor(Color.GREEN);
        canvas.drawCircle(0, 0, 20, p1);
        canvas.drawLine(0, 0, 0, 1000, p1);
        canvas.drawLine(0, 0, 1000, 0, p1);
        
        canvas.restore();//恢复到前一个坐标系
        
        //将坐标系绕px,py 旋转30度
        canvas.rotate(30, px, py);
        canvas.drawPoint(px, py, p1);
        
        //画出原点的位置,并且画出x轴与y轴
        p1.setColor(Color.BLUE);
        canvas.drawCircle(0, 0, 20, p1);
        canvas.drawLine(0, 0, 0, 1000, p1);
        canvas.drawLine(0, 0, 1000, 0, p1);
        super.onDraw(canvas);
}

image

转载于:https://www.cnblogs.com/QiaoJun-Fighting/p/4601910.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值