Android自定义形状波浪进度

2024-08-27  本文已影响0人  王郁

title: 自定义形状波浪进度
date: 2017-7-24 12:41:59
tags:


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

![20170724_wave_progress.gif](https://img.haomeiwen.com/i6854811/fbb0871f9b9229df.gif?imageMogr2/auto-orient/strip

思路

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

20170724_sin.png
    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);
    }

注意事项

setZOrderOnTop(true);
mHolder.setFormat(TRANSLUCENT);

完整源码:

https://github.com/wangyucode/WaveProgress

上一篇 下一篇

猜你喜欢

热点阅读