Android自定义形状波浪进度

今天碰到个需求,要求以波浪进度填充自定义透明形状,废话不多说,直接上最终效果图
wave-progress

思路

通过判断Bitmap对象的像素颜色,对非透明像素进行颜色更改。波浪曲线采用sin曲线π到2π区间段,和将时间取余并和x坐标相加得到波浪y轴坐标,再加上百分比*Bitmap高度。核心算法如下:
sin

    private int getWaveY(int x) {
        double sinX = Math.PI + (((((System.currentTimeMillis() / (1000 / waveSpeed)) + x) % waveLength)) / (double) waveLength * Math.PI);
        int waveHeight = (int) (waveHeightMax * (Math.sin(sinX) + 1));
        int y = (int) ((100 - progress) / 100f * bitmap.getHeight());
        y -= waveHeight;
        return y;
    }

这里的waveSpeedwaveLengthwaveHeightMax均定义成全局变量,可以很方便的定制波浪移动速度、波浪长度、波浪高度。

使用SurfaceView

为了达到比较好的性能,使用SurfaceView在子线程绘图。

性能优化

因为这里涉及逐个像素操作,所以遍历的运算量很大,一定要对遍历的量进行控制,否则会很卡。

我这里采用控制图片大小的方式

***
    bitmap = setBitmapSize(bitmap, calculateSize * bitmap.getWidth() / bitmap.getHeight(), calculateSize);

***
    /**
     * 缩放图片
     *
     * @param bitmap    原图片
     * @param newWidth
     * @param newHeight
     * @return
     */
    private Bitmap setBitmapSize(Bitmap bitmap, int newWidth, int newHeight) {
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        float scaleWidth = (newWidth * 1.0f) / width;
        float scaleHeight = (newHeight * 1.0f) / height;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
    }

通过calculateSize控制循环次数在有限的范围内,并在最终绘制Bitmap时使用区域绘制函数:

    private void draw() {
        Canvas canvas = mHolder.lockCanvas();
        canvas.drawBitmap(bitmap, rectBitmap, rectCanvas, mPaint);
        mHolder.unlockCanvasAndPost(canvas);
    }

注意事项

  • 为了达到SurfaceView透明效果,需要加入以下两句代码
setZOrderOnTop(true);
mHolder.setFormat(TRANSLUCENT);
  • Drawable中得到的Bitmap不能直接setPixel(),必须重新Bitmap.createBitmap(),或Bitmap.copy(),使得isMutable属性为true,得到新的Bitmap对象才能操作像素,否则会报IllegalStateException

完整源码:

https://github.com/wangyucode/WaveProgress

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值