Android自定义View系列之正弦曲线

作者: 广州小拳拳 | 来源:发表于2017-05-24 21:51 被阅读245次

写在前面

最近在找工作,安装了某勾网 APP,登录后看到用户信息绿色背板那骚气的波浪。


某勾的波浪

让我看看性能如何,在开发者模式里开启了 GPU 渲染情况信息展示。


惨不忍睹

非常明显,百度上的文章抄来抄去,错了大家一起错,在 onDraw 方法里执行成百上千次 canvas.drawXXX 方法,性能不差才怪。

改良方法

我试着用 Path 绘制路径这个 API。onDraw 代码如下:

// 振幅
int amplitude = 20;

int height = getHeight();
// 波长
int width = getWidth();
int index = 0;

mPath.reset();
mPath.moveTo(0, 0);
while (index <= width) {
    float endY = (float) (Math.sin((float) index / (float) width * 2f * Math.PI + mTheta)
          * (float) amplitude + height - amplitude);
    mPath.lineTo(index, endY);
    // Log.e("xxx", String.format("(%.4f, %.4f)", (float) index, endY));
    index++;
}
mPath.lineTo(index - 1, 0);
mPath.close();

canvas.drawPath(mPath, mPaint);

看下性能如何:


还可以还可以

onDraw 里只有一次 drawXXX 方法,性能已经达标,接下来定时修改那个 mTheta 变量,波浪就会动起来了。

总结

百度虽好,可不能照搬照抄。

源码放置了自定义 View 集合,找到 WaveView 那个类就可以看到了。
GitHub 地址

相关文章

网友评论

  • HuBoZzz:你好我有个疑问: while (index <= width) {//画曲线
    float endY = (float) (Math.sin((float) index / (float) width * 2f * Math.PI + mTheta)
    * (float) amplitude + height - amplitude);
    mPath.lineTo(index, endY);
    // Log.e("xxx", String.format("(%.4f, %.4f)", (float) index, endY));
    index++;
    }
    ----------------------------------
    mPath.lineTo(index, endY);在循环中画的不应该是个横着的波浪线么?为什么在实际中是个三角形,
    mPath.lineTo(index - 1, 0);
    mPath.close();
    ---------------------------
    这句是让其组成封闭的矩形的么?.close()不是起点和终点连线么?为什么成了一个封闭的矩形?。
    HuBoZzz:@hayukleung 嗯嗯,这点我知道的,执行while 循环后应该是个横着的波浪线~,那上面的矩形怎么弄得呢?
    广州小拳拳:@HuBoZzz lineTo 这个方法的起点是 mPath 最近一次的终点,每一小段的直线连接起来就是曲线了
    HuBoZzz:如果只执行while循环里的感觉每天线的起始点都是(0,0)点,这不科学吧

本文标题:Android自定义View系列之正弦曲线

本文链接:https://www.haomeiwen.com/subject/ysooxxtx.html