android使用Path绘制出多边形
作者:zhoushenxian 发布时间:2021-11-11 19:53:38
在讲使用path绘制多边形时,讲下Canvas的translate(),rotate()方法的使用,本博客中会使用这方面的知识,先单独讲下,搞懂了这个,下面讲path绘制多边形就简单的多,我们知道每次我们使用canvas.draw...()绘制什么图形的时候,都是创建了一个新的图层,如果不知道图层是啥意思,就去看下我之前写的关于canvas基础,有讲这方面的,其实你可以理解成每次新创建了一个activity,然后把这个activity压入栈中,translate()是画布平移,其实每次画布还是同一个画布,通过paint绘制的图形都是在这同一个canvas上,但是绘制的内容跟你是否使用了translate()有关系,下面通过简单的demo来演示下:
package smart.com.pathview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* 绘制多边形
*/
public class PathmMultiView extends View {
private Paint paint;
public PathmMultiView(Context context) {
this(context,null);
}
public PathmMultiView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public PathmMultiView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setTextSize(24);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GREEN);
canvas.drawText("杭州是个美丽的城市",20,20,paint);
paint.setColor(Color.RED);
canvas.drawPoint(100,100,paint);
canvas.translate(100,100);
paint.setColor(Color.BLUE);
canvas.drawText("杭州是个美丽的城市",0,0,paint);
}
}
效果:
上面的红点是坐标点(100,100)的位置,为什么绘制的蓝色的文字是在坐标点(100,100)的位置呢?是因为你canvas使用了translate(100,100)也就是x,y坐标都平移了100px,这个是根据你当前的view的左上角坐标为原点进行平移的,平移肯定是相对那个点进行平移的,不人为的去设置画布的颜色,默认都是透明的,否则你draw...2次,上次绘制的内容就被覆盖了,文字太苍白无力,就好像你对一个女孩说一千篇我爱你,还不如说你在杭州买了套房来的实际,就好像香港有一个电影中的台词是这么说的,这是一个最好的时代,也是一个最坏的时代,好了废话不多说,图,我要图!
关于如何恢复画布有三种情况 就以平移例子来讲
第一种:
你x,y平移了多少后,我们知道x>0是向右平移,x<0是向左平移,那么恢复就很简单了
canvas.translate(-x,-y)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GREEN);
canvas.drawText("杭州是个美丽的城市",20,20,paint);
paint.setColor(Color.RED);
canvas.drawPoint(100,100,paint);
canvas.translate(100,100);
paint.setColor(Color.BLUE);
canvas.translate(-100,-100);
canvas.drawText("杭州是个美丽的城市",20,20,paint);
}
效果:
你会发现绿色和蓝色是重叠了。
第二种:
配套使用canvas.save() canvas.restore() ;save()是绑定画布,restore()是让画布恢复到最初的状态
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GREEN);
canvas.save();
canvas.drawText("杭州是个美丽的城市",20,20,paint);
paint.setColor(Color.RED);
canvas.drawPoint(100,100,paint);
canvas.translate(100,100);
paint.setColor(Color.BLUE);
canvas.restore();
canvas.drawText("杭州是个美丽的城市",20,20,paint);
}
效果:
第三种:
int count = canvas.save(Canvas.MATRIX_SAVE_FLAG);//这个看你是在canvas.draw...哪里调用了,就相当于保存画布
canvas.restoreToCount(count);//恢复
画图:
现在讲下画多边形,先确定下思路:
1:把这个多边形的外切圆画出来当做一个辅助的参考目标,
2:计算多个点的坐标然后连接成一条线
如图分析:
现在根据这个思路把代码实现下:
代码如下:
package smart.com.pathview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
/**
* 绘制多边形
*/
public class PathmMultiView extends View {
private Paint paint;
private Path path;
private int width,height;
public PathmMultiView(Context context) {
this(context,null);
}
public PathmMultiView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public PathmMultiView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}
private void initPaint() {
width = 400;
height = 400;
path = new Path();
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(5);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(width,height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawMultShape(canvas,6,width/2);
}
/**
* @param canvas 画布
* @param count 绘制几边形
* @param radius //外圆的半径
*/
public void drawMultShape(Canvas canvas,int count,float radius){
canvas.translate(radius,radius);//
if(count<5){
return;
}
for (int i=0;i<count;i++){
if (i==0){
path.moveTo(radius*cos(360/count*i),radius*sin(360/count*i));//绘制起点
}else{
path.lineTo(radius*cos(360/count*i),radius*sin(360/count*i));
}
}
paint.setStrokeWidth(3);
path.close();
paint.setColor(Color.GREEN);
canvas.drawPath(path,paint);
//因为我下面不再绘制内容了 所以画布就不恢复了
}
float sin(int num){
return (float) Math.sin(num*Math.PI/180);
}
float cos(int num){
return (float) Math.cos(num*Math.PI/180);
}
}
效果:
哪绘制正8变形呢?好说,直接
drawMultShape(canvas,6,width/2); 第二个参数就是几边形的改为8就ok了,试试看看效果:
就一句话,哦了。
还有一个问题就是如果所绘制的是多边形,但是好像形状不一样,怎么修改,这个时候只要旋转画布就行了,比如这张图片:
使用canvas.rotate(30);旋转30度后是这样的
当然你要在绘制这个图形之前对画布进行旋转,不然不起作用,网上有些五角星的效果,是怎么实现的呢?比如这样的效果:
这是正6变形所形成的星星形状,分析如图:
来源:https://blog.csdn.net/coderinchina/article/details/53509643


猜你喜欢
- 一、问题场景使用Logger.error方法时只能打印出异常类型,无法打印出详细的堆栈信息,使得定位问题变得困难和不方便。二、先放出结论Lo
- 说明:实现功能:(1)屏幕右半部分上滑,声音变大,下滑,声音变小 屏幕左半部分上滑,亮度变大,下滑,亮度变小(2)如果亮度>1或者小于
- 实例如下:func exitApplication() { let app = UIApplication.sh
- 调用微信接口前需要准备的内容。1.微信公众平台的appid2.微信公众平台的secret3..获取tokenid4.获取ticket5.生成
- 一、简介应用程序配置文件(App.config)是标准的 XML 文件,XML 标记和属性是区分大小写的。它是可以按需要更改的,开发人员可以
- 说在前面大一软件工程在读,java萌新一只,第一次写博客,技术很菜勿喷。如有错误欢迎指出!这个小程序是给朋友的生日礼物,耗时半天,实际写起来
- 问题描述在使用mybatis进行开发的时候,由于可以动态拼接sql,这样大大方便了我们。但是也有一定的问题,当我们动态sql拼接的块很多的时
- list页面的字段要求可以根据用户的喜好进行排序,所以每个用户的字段都对应着不同的顺序(字段顺序存数据库),我们从数据库里取出来的值是对象,
- 在application.properties中填写中文信息,在读取该文件时会出现中文乱码问题。比如:application.propert
- 想要在Ubuntu上运行java程序,可以将java程序编译成功后打包,然后在Ubuntu上用命令执行jar文件具体操作如下:1、Windo
- 1.先来张效果图2.自定义一个角标工具类BottomBarView 。** * Created by Administrator on 20
- 前言最近在逛博客的时候看到了有关Redis方面的面试题,其中提到了Redis在内存达到最大限制的时候会使用LRU等淘汰机制,然后找了这方面的
- 一、Spring Boot任务线程池线程池的作用防止资源占用无限的扩张调用过程省去资源的创建和销毁所占用的时间在高并发环境下,不断的分配新资
- 微信小程序 跳转页面小程序页面有2种跳转,可以在wxml页面或者js中:1,在wxml页面中: <navigator url=&quo
- 1,验证传入路径是否为正确的路径名(Windows系统,其他系统未使用)Java代码 // 验证字符串是否为正确路径名的正则表达式 
- ODT文档格式一种开放文档格式(OpenDocument Text)。通常,ODT格式的文件可以使用LibreOffice Writer、M
- 记录web项目部署到阿里云服务器步骤(使用 web项目、阿里云服务器、Xftp、Xshell),敬请参考和指正1.将要部署的项目打包成WAR
- 一、什么是CharacterEncodingFilter官方解释如下是spring内置过滤器的一种,用来指定请求或者响应的编码格式。在web
- 在我们的程序当中如果要实现类似《360软件管家》的功能,就要解决两个问题,首先是要判断该程序已有一个实例在运行,其次是要将已运行的应用程序实
- 命令模式定义:将请求封装成对象,这可以让你使用不同的请求、队列、或者日志来参数化其他对象。何时使用命令模式?当需要将发出请求的对象和执行请求