Android:视图绘制(三) ------Path介绍

Path 顾名思义是路径的意思。前文我们讲过Canvas提供了很多方法来绘制各种图形。但是,有时我们的需求不是常规的图形,那么就需要用到本文要讲的Path类。

Canvas里提供了一个drawPath(Path path, Paint paint)方法,来绘制我们的Path对象。

下面就让我们一起来了解一下Path对象。


构造方法

Path()
Path(Path src)

Path提供了两种构造方法,一种是无参的,一种是根据一个Path对象来生成的。


addXXX系列方法

前文讲过Canvas提供了一系列drawXXX的方法,来绘制想矩形,圆,椭圆,圆弧等各种图形。Path,作为路径,当然也提供了对应的方法。不太了解的请移步《Android:视图绘制(一) ——基本的绘图操作Paint和Canvas》

因为方法与前文所讲差别不大,对于这一系列的就不一一介绍了,下面以矩形为例:

addRect(RectF rect, Direction dir)
addRect(float left, float top, float right, float bottom, Direction dir)

Path这一系列方法都是以add开头的,参数RectF和float left, float top, float right, float bottom,前文也有介绍,相信大家都很熟悉。

下面来看 Direction ,路径的方向,其是Path中的一个枚举型变量,并提供了两个可选值

CW  顺时针
CCW 逆时针
// Direction 为 CW 的Path对象
Path pathCW = new Path();
pathCW.addRect(100, 100, 400, 400, Path.Direction.CW);

// Direction 为 CCW 的Path对象
Path pathCCW = new Path();
pathCCW.addRect(100, 500, 400, 800, Path.Direction.CCW);

canvas.drawPath(pathCW, mPaintLine);
canvas.drawTextOnPath("Path.Direction.CW", pathCW, 0, 0, mPaintLine);
canvas.drawPath(pathCCW, mPaintLine);
canvas.drawTextOnPath("Path.Direction.CCW", pathCCW, 0, 0, mPaintLine);

可以看见我们分别以顺时针和逆时针声明了一个Path对象,并调用Canvas的drawPath方法画出来。为了给大家体现出效果,又调用了Canvas的drawTextOnPath,画出文字。

这里写图片描述

这样,就可以很清晰的看出CW和CCW的区别。

Path还提供了一些图形方法,大致相同。这些方法完全可以用Canvas对应的方法代替,就不多做介绍了。

addArc          圆弧
addRoundRect    圆角矩形
addCircle       圆 
addOval         椭圆

以点画线

这部分讲的方法,才是Path类的特别之处,也是我们为什么要用到Path类的原因。

moveTo(float x, float y)

官网解释:Set the beginning of the next contour to the point (x,y).

也就是设置我们要绘制的图形的起点(x,y)。

lineTo(float x, float y)

官网解释:Add a line from the last point to the specified point (x,y). If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).

意思是:以之前设置过的最后一个点到这个点(x,y)连线,如果之前没有调用moveTo(),也就是说连起点都没设置,那默认是以(0,0)为起点的。

close()

官网解释:Close the current contour. If the current point is not equal to the first point of the contour, a line segment is automatically added.

意思是闭合我们的图形,如果不是只有一个点的话,就会加一条线。

 // 画一个三角形
 Path path = new Path();
 path.moveTo(100, 100); // 如果不加这句,默认以(0,0)为起点。
 path.lineTo(200, 400);
 path.lineTo(300, 300);
 path.close();
 canvas.drawPath(path, mPaintLine);

这里写图片描述

可以看出,当调用close方法时,以最后一个点(300,300)到起点(100,100)做了一条连线。

rMoveTo(float x, float y)

官网解释:Set the beginning of the next contour relative to the last point on the previous contour. If there is no previous contour, this is treated the same as moveTo().

可以看见这个方法比前面的moveTo,多了一个字母 r .这里 r 的意思就是 relative(相对)的意思,从官网的解释上也能看出,就是在前一个点的基础上增加了(x,y),如果是第一个点,等同于 moveTo().

rLineTo(float x, float y)

官网解释:Same as lineTo, but the coordinates are considered relative to the last point on this contour. If there is no previous point, then a moveTo(0,0) is inserted automatically.

这个方法较lineTo也是多了一个 relative(相对)的意思。

Path path = new Path();
path.moveTo(100, 100); // 如果不加这句,默认以(0,0)为起点。
path.lineTo(200, 400);
path.lineTo(300, 300);
path.close();

path.rMoveTo(100, 100); // 在上一个点(300,300)基础上加了(100,100),所以这个点是(400,400)
path.rLineTo(100, 100); // 在上一个点(400,400)基础上加了(100,100),所以这个点是(500,500)

canvas.drawPath(path, mPaintLine);

这里写图片描述

值得一说的是,上面的例子中,Paint的填充模式为Paint.Style.STROKE。如果我们把Paint的填充模式设置为Paint.Style.FILL的话,直线是不会绘制出来的,因为直线,没有可供填充的区域。


到此,讲的Path都是以直线连接各个点,来构成图形。其实Path中还封装了贝塞尔曲线(有没有很高大上,其实用起来还是蛮简单的),可以绘制曲线的效果。

贝塞尔曲线有控制点的概念,通过控制点来绘制出特定的曲线。所以,只有两个点的话,就是一条直线。

quadTo(float x1, float y1, float x2, float y2)

官方解释:Add a quadratic bezier from the last point, approaching control point (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).

意思就是增加一个二次的贝塞尔曲线,以 moveTo(x,y) 为起点(如果没有设置默认为(0,0)),(x2,y2)为终点, (x1,y1)为控制点。

cubicTo(float x1, float y1, float x2, float y2, float x3, float y3)

官方解释:Add a cubic bezier from the last point, approaching control points (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).

cubicTo 方法构建的是一个三次的贝塞尔曲线,以第一个点为起点,(x3,y3)为终点,其余点为控制点

看一个例子:

 // 二阶贝塞尔曲线
 Path pathBezier = new Path();
 pathBezier.moveTo(100, 100);
 pathBezier.quadTo(200, 400, 100, 600);
 canvas.drawPath(pathBezier, mPaintLine);

 // 以二阶贝塞尔曲线的所有点连线
 Path path = new Path();
 path.moveTo(100, 100);
 path.lineTo(200, 400);
 path.lineTo(100, 600);
 canvas.drawPath(path, mPaintText);

 // 三阶贝塞尔曲线
 Path pathCubic = new Path();
 pathCubic.moveTo(400,100);
 pathCubic.cubicTo(300,300,500,400,400,600);
 canvas.drawPath(pathCubic, mPaintLine);

 // 以三阶贝塞尔曲线的所有点连线
 path.moveTo(400, 100);
 path.lineTo(300, 300);
 path.lineTo(500, 400);
 path.lineTo(400, 600);
 canvas.drawPath(path, mPaintText);

这里写图片描述

跟前面的一样,quadTo和cubicTo都有其对应的相对方法(即前缀为 r 的)rQuadTo和rCubicTo,也是相对的意思,值得注意的是因为这个方法参数不是一个点,所有的相对都是针对第一个点的。

rQuadTo(float dx1, float dy1, float dx2, float dy2) dx2和dy2,是相对于 dx1和dy1的。
rCubicTo(float x1, float y1, float x2, float y2, float x3, float y3) x2,y2 和x3,y3都是相对于 x1,y1的。

arcTo(RectF oval, float startAngle, float sweepAngle)
arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)

官方解释:Append the specified arc to the path as a new contour. If the start of the path is different from the path’s current last point, then an automatic lineTo() is added to connect the current contour to the start of the arc. However, if the path is empty, then we call moveTo() with the first point of the arc.

意思就是说在Path上加一个圆弧,如果Path上的最后一个点不是圆弧的起点,就会在最后一个点和圆弧起点做一个连线。如果path是空的话,就是没设置过任何数据的时候,会把圆弧的起点最为Path的起点。

 Path path = new Path();
 path.moveTo(100, 100);
 RectF rectF = new RectF(200, 200, 400, 400);
 path.arcTo(rectF, 0, 80, false);
 canvas.drawPath(path, mPaintLine);
 canvas.drawRect(rectF, mPaintLine);

这里写图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android绘制自定义地图可以通过以下步骤实现: 1. 获取地图数据:首先,需要获取自定义地图的数据,这可以是由地图提供者提供的矢量数据、栅格数据或者是在地图编辑器中创建的自定义地图图层。 2. 解析地图数据:将获取到的地图数据解析成可以在Android绘制的格式。这可能涉及到解析矢量数据、转换图像数据格式或者解析自定义地图文件格式。 3. 创建自定义绘制视图:在Android中,我们可以使用自定义绘制视图来实现绘制自定义地图。通过继承View类或者SurfaceView类,并重写相应绘制方法(如onDraw方法),可以在画布上绘制地图数据。 4. 绘制地图数据:在自定义绘制视图中,通过使用Canvas对象和Paint工具等工具,可以将解析好的地图数据绘制到画布上。根据需求,可以自定义地图的样式、颜色、线条粗细等。 5. 处理地图交互:在绘制地图的同时,还可以处理一些地图交互操作,例如实现点击地图位置获取地理坐标、实现地图缩放和平移等操作。可以通过添加触摸事件监听器来实现相应的交互处理。 6. 更新地图数据:如果自定义地图需要动态更新,可以根据需要实现数据更新的逻辑,例如定期从服务器获取最新地图数据,并重新解析和绘制地图。 7. 优化性能:在绘制自定义地图时,需要考虑性能优化,避免频繁的绘制操作导致卡顿。可以使用缓存技术、合并绘制操作、使用硬件加速等手段来提高绘制效率。 总之,Android绘制自定义地图的关键是获取并解析地图数据,然后通过自定义绘制视图来展示地图数据,并处理相应的地图交互操作。 ### 回答2: Android绘制自定义地图可以通过以下步骤实现: 1. 准备地图数据:首先需要获取自定义地图数据,可以是地图的矢量数据或者图片,如SVG格式的矢量地图或者PNG格式的图片地图。可以从地图提供商获取或者自行制作。 2. 绘制地图背景:在Android的绘图环境Canvas上创建一个画布,并且使用地图背景色填充整个画布。 3. 坐标转换:根据地图数据和设备屏幕的尺寸,将坐标进行转换,使得地图上的坐标点对应到屏幕上的实际像素点。 4. 绘制地图要素:根据地图数据,将地图要素逐个绘制到画布上,如绘制地图的道路、河流、建筑等等。可以借助Android的Canvas来完成这些绘制操作,如使用画笔设置颜色、线宽等属性,使用路径(Path)来绘制直线、曲线,使用矩形(Rect)来绘制建筑等等。 5. 绘制标注和图标:根据需要,在地图上绘制标注和图标,如标记地点的名称、行政区划边界、POI点等等。可以使用Canvas的文本绘制功能来绘制标注的文本,可以使用Bitmap来绘制图标。 6. 交互操作:可以通过触摸事件来实现对地图的交互操作,如放大、缩小、平移地图等。可以根据用户的操作,重新计算地图的显示范围并更新画布上的绘制内容。 7. 地图样式和主题:可以根据需求自定义地图的样式和主题,如修改地图要素的颜色、线宽、字体等属性,调整地图的显示效果。 绘制自定义地图需要有一定的绘图技巧和地理知识,同时需要理解Android的绘图原理和API。通过上述步骤,可以实现在Android应用中绘制出自定义的地图,满足特定需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值