当前位置: 移动技术网 > 移动技术>移动开发>Android > Android水波纹载入控件CircleWaterWaveView使用详解

Android水波纹载入控件CircleWaterWaveView使用详解

2019年07月29日  | 移动技术网移动技术  | 我要评论

一、效果图

本控件已上传github,欢迎star和fork,项目地址:circlewaterwaveview

二、设计思路

观察效果图,可以看出,该自定义控件由三个部分构成:外圆、内圆、正弦曲线。他们的关系如下图:

因为控件是动态的,所以我们需要一个线程去不停地绘制,所以我选择了surfaceview来作为该控件地父类。该控件地核心是如何去绘制波浪,我采用如下的思路来进行内圆下部地绘制。利用内圆与正弦曲线地交集,来绘制。 

核心代码如下:

/**
 * 绘制图像
 *
 * @author luxun
*/
  private void drawcanvas(canvas canvas) {
    if (canvas == null)
      return;
    //画背景圆圈
    canvas.setdrawfilter(new paintflagsdrawfilter(0, paint.anti_alias_flag | paint.filter_bitmap_flag));
    canvas.drawcircle(mcenterpoint.x, mcenterpoint.y, moutradius, moutcirclepaint);
    canvas.drawcircle(mcenterpoint.x, mcenterpoint.y, mradius, mcirclepaint);
    if (mstart) {
      //计算正弦曲线的路径
      int mh = mcenterpoint.y + mradius - mcurrenthight;
      int length = 2 * moutradius;
      path path = new path();
      path.moveto(0, mh);
      for (int i = 0; i < length; i++) {
        int x = i;
        int y = (int) (math.sin(math.toradians(x + mtranx) / amplitude) * mradius / increase);
        path.lineto(x, mh + y);
      }
      path.lineto(length, mh);
      path.lineto(length, mcenterpoint.y + mradius);
      path.lineto(0, mcenterpoint.y + mradius);
      path.lineto(0, mh);
      canvas.save();//保存画布状态
      //这里与圆形取交集,除去正弦曲线多画的部分
      path pc = new path();
      pc.addcircle(mcenterpoint.x, mcenterpoint.y, mradius, path.direction.ccw);
      canvas.clippath(pc, region.op.intersect);//切割画布
      canvas.drawpath(path, mwaterpaint);
      //绘制文字
      canvas.drawtext(flownum + "%", mcenterpoint.x, mcenterpoint.y + mtextsise / 2, mtextpaint);
      canvas.restore();//恢复画布状态
    }
  }

三、性能优化

绘制线程如下:

 /**
   * 绘制界面的线程
   *
   * @author luxun
 */
  private class renderthread implements runnable {
    @override
    public void run() {
      // 不停绘制界面,这里是异步绘制,不采用外部通知开启绘制的方式,水波根据数据更新才会开始增长
      while (isdrawing) {
        if (mwatertaget > mcurrenthight) {
          mcurrenthight = mcurrenthight + mupspeed;
          if (mwatertaget <= mcurrenthight) {
            mcurrenthight = mwatertaget;
          }
        }
        if (mstart) {
          if (mtranx > mradius) {
            mtranx = 0;
          }
          mtranx -= mwaterspeed;
        }
        drawui();
        systemclock.sleep(25);//控制刷新速率,减少cpu占用
      }
    }
  }

通过为surfaceholder添加监听,来控制绘制线程。当控件被隐藏不在前台显示时,自动结束绘制线程,当控件显示在前台时,再次开启绘制。

@override
  public void surfacecreated(surfaceholder surfaceholder) {
    isdrawing = true;
    new thread(renderthread).start();
  }

  @override
  public void surfacechanged(surfaceholder surfaceholder, int format, int width, int height) {
    int minlength = math.min(width, height);
    moutradius = minlength / 2;
    mradius = (int) (0.5 * (minlength - moutstrokewidth));
    mcenterpoint = new point(minlength / 2, minlength / 2);
    if (progress != 0) {
      setprogress(progress);
    }
  }

  @override
  public void surfacedestroyed(surfaceholder surfaceholder) {
    isdrawing = false;
  }

四、属性化

部分设置属性,除了通过代码设置外,同时也加入了在xml文件中,直接以属性赋值的操作。

app:textcolor="#00ff00"
app:watercolor="#00ff00"
app:strokecolor="#00ff00"
app:backgroudcolor="#00ff00"
app:amplitude="1.0"[水波振幅]
app:max="1000"
app:progress="500"
app:increase="6.0"[水波涨幅]
app:upspeed="3"[上涨速度]
app:waterspeed="8"[移动速度]
app:strokesize="4dp"
app:textsize="20dp"

五、后记

代码已经上传github,欢迎有兴趣的朋友去看看。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网