canvas教程

Android自定义View之圆形进度条总结(5)

字号+ 作者:H5之家 来源:H5之家 2017-05-19 13:06 我要评论( )

这里主要讲一下刻度的绘制。刻度绘制主要使用 Canvas 类的 save()、rotate()和restore() 方法,当然你也可以使用 translate() 方法对坐标系进行平移,方便计算。 /***用来保存Canvas的状态。save之后,可以调用Canv

这里主要讲一下刻度的绘制。刻度绘制主要使用 Canvas 类的 save()、rotate()和restore() 方法,当然你也可以使用 translate() 方法对坐标系进行平移,方便计算。

/**  * 用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。  */  public void save()     /**  * 旋转一定的角度绘制图像  * @param degrees 旋转角度  * @param x 旋转中心点x轴坐标  * @param y 旋转中心点y轴坐标  */  public void rotate(float degrees, float x, float y)     /**  * 在当前的坐标上平移(x,y)个像素单位  * 若dx <0 ,沿x轴向上平移; dx >0  沿x轴向下平移  * 若dy <0 ,沿y轴向上平移; dy >0  沿y轴向下平移  */  public void translate(float dx, float dy)     /**  * 用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。  */  public void restore()   private void drawDial(Canvas canvas) {     int total = (int) (mSweepAngle / mDialIntervalDegree);     canvas.save();     canvas.rotate(mStartAngle, mCenterPoint.x, mCenterPoint.y);     for (int i = 0; i <= total; i++) {         canvas.drawLine(mCenterPoint.x + mRadius, mCenterPoint.y, mCenterPoint.x + mRadius + mArcWidth, mCenterPoint.y, mDialPaint);         canvas.rotate(mDialIntervalDegree, mCenterPoint.x, mCenterPoint.y);     }     canvas.restore();  }  

关于 Canvas 的画布操作可以参考这篇文章:安卓自定义View进阶-Canvas之画布操作

水波纹效果的进度条

水波纹效果的进度条实现需要用到贝塞尔曲线,主要难点在于 绘制区域的计算 和 波浪效果 的实现,其余的逻辑跟上述两种进度条相似。

这里使用了 Path 类,该类在 Android 2D 绘图中是非常重要的,Path 不仅能够绘制简单图形,也可以绘制这些比较复杂的图形。也可以对多个路径进行布尔操作,类似设置 Paint 的 setXfermode() ,具体使用可以参考这篇博客:安卓自定义View进阶-Path基本操作。这里就不再赘述,有机会自己也会对 Android 自定义 View 的知识进行总结,不过,感觉应该了了无期。

继续上示意图,请叫我灵魂画手~

Android自定义View之圆形进度条总结

图中黑色的圆为我们要绘制的进度条圆,黑色的曲线为初始状态的的波浪,该波浪使用贝塞尔曲线绘制,其中奇数的点为贝塞尔曲线的起始点,偶数的点为贝塞尔曲线的控制点。例如:1——>2——>3就为一条贝塞尔曲线,1 是起点,2 是控制点,3 是终点。从图中可以看到波浪在园内圆外各一个(1—>5 和 5->9),通过对波浪在 x 轴上做平移,即图中蓝色实线,来实现波浪的动态效果,所以一个波浪的完整动画效果需要有两个波浪来实现。同理,通过控制 y 轴的偏移量,即图中蓝色虚线,可以实现波浪随进度的上涨下降。

贝塞尔曲线上起始点和控制点的计算如下:

/**  * 计算贝塞尔曲线上的起始点和控制点  * @param waveWidth 一个完整波浪的宽度  */  private Point[] getPoint(float waveWidth) {     Point[] points = new Point[mAllPointCount];     //第1个点特殊处理,即数组的中心     points[mHalfPointCount] = new Point((int) (mCenterPoint.x - mRadius), mCenterPoint.y);     //屏幕内的贝塞尔曲线点     for (int i = mHalfPointCount + 1; i < mAllPointCount; i += 4) {         float width = points[mHalfPointCount].x + waveWidth * (i / 4 - mWaveNum);         points[i] = new Point((int) (waveWidth / 4 + width), (int) (mCenterPoint.y - mWaveHeight));         points[i + 1] = new Point((int) (waveWidth / 2 + width), mCenterPoint.y);         points[i + 2] = new Point((int) (waveWidth * 3 / 4 + width), (int) (mCenterPoint.y + mWaveHeight));         points[i + 3] = new Point((int) (waveWidth + width), mCenterPoint.y);     }     //屏幕外的贝塞尔曲线点     for (int i = 0; i < mHalfPointCount; i++) {         int reverse = mAllPointCount - i - 1;         points[i] = new Point(points[mHalfPointCount].x - points[reverse].x,                 points[mHalfPointCount].y * 2 - points[reverse].y);     }     return points;  }  

以上,我们已经获取到绘制贝塞尔曲线所需的路径点。接下来,我们就需要来计算出绘制区域,即使用 Path 类。

Android自定义View之圆形进度条总结

紫色区域为贝塞尔曲线需要绘制的整体区域。

Android自定义View之圆形进度条总结

红色区域为上图紫色区域与圆的交集,也就是波浪要显示的区域

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 实时监控Android设备网络封包

    实时监控Android设备网络封包

    2017-05-19 15:04

  • view的绘制流程.doc

    view的绘制流程.doc

    2017-05-15 18:03

  • android双缓冲绘图技术分析

    android双缓冲绘图技术分析

    2017-05-14 15:02

  • 包邮现货Android和PHP开发最佳实践第2版/安卓移动开发教程书籍/P

    包邮现货Android和PHP开发最佳实践第2版/安卓移动开发教程书籍/P

    2017-05-14 09:02

网友点评