前言

现在我们的App中基本都会有闪屏页面,而闪屏页中大多又都会加入广告信息或者我们自己logo等宣传图片的展示,类似如下效果:

思路

使用自定义View,通过View的重绘方法Invalidate()onDraw()中不断绘制不同弧度的圆弧来改变显示进度,是不是很简单?下面就来一起看一下具体的实现啦~

  1. 确定绘制位置,首先在onDraw()中获取View的宽高,定义出一个矩形为我们的绘制范围:
int width = this.getWidth();
        int height = this.getHeight();

        if (width != height) {
            int min = Math.min(width, height);
            width = min;
            height = min;
        }

        //定义矩形的上下左右位置 mStrokeWidth为画笔的宽度
        //为什么要从画笔宽度/2位置开始,请看下图啦,红色是画笔的路径,黑色就是我们定义的矩形位置
        mRectF.left = mStrokeWidth / 2;
        mRectF.top = mStrokeWidth / 2;
        mRectF.right = width - mStrokeWidth / 2;
        mRectF.bottom = height - mStrokeWidth / 2;
  1. 绘制背景颜色,这里一半都是给一个半透明的颜色,因为这里面一半都会显示个跳过或者倒计时时间的文字,不透明看不到下面的图片,全透明又有可能字体颜色和底部图片颜色近似而看不清。so~ 调整下画笔颜色和填充模式就好啦,canvas背景色要设置为全透明:
//设置画布为透明
        canvas.drawColor(Color.TRANSPARENT);

        //画个半透明的圆当背景
        mPaint.setColor(Color.parseColor("#33000000"));
        //设置画笔为填充模式
        mPaint.setStyle(Paint.Style.FILL);
        //画一个椭圆
        canvas.drawOval(mRectF, mPaint);
  1. 调整画笔属性 绘制圆弧,这里需要注意的是绘制圆弧时的起始角度是三点钟方向是0度,12点方向是-90度。
//设置画笔
        mPaint.setAntiAlias(true);              //抗锯齿
        mPaint.setColor(paintColor);            //设置画笔颜色
        mPaint.setStyle(Paint.Style.STROKE);    //设置画笔填充模式 
        mPaint.setStrokeWidth(mStrokeWidth);    //设置画笔宽度

        //绘制圆弧  第一个参数是我们定义好的矩形,用来控制绘制区域,也可以直接传入上下左右四个边框的距离来控制
        //          第二个参数是圆弧的起始角度
        //          第三个参数是绘制的角度范围,主要就是通过这个参数控制
        //          第四个参数表示是否连接到圆心,true连接了就是扇形了 false不连接就是圆弧
        //          mProgress是当前进度,-号是为了控制绘制方向
        canvas.drawArc(mRectF, -90, -(mProgress / mMaxProgress) * 360, false, mPaint);
  1. 时间进度计算 这里的方法有待优化,感觉不是特别好。现在是通过循环控制短时间sleep,使用View的重绘方法来更新绘制进度,这里需要注意的是在子线程必须调用postInvalidate()方法来进行重绘。
/**
     * 开始倒计时
     *
     * @param time 倒计时时间 毫秒值
     */
    public void startDownTime(final long time) {
        //最大进度
        mMaxProgress = 100;
        //开启子线程来做睡眠操作
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = (int) mMaxProgress; i >= 0; i--) {
                    try {
                        Thread.sleep((long) (time / mMaxProgress));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    mProgress = (float) i;
                    //子线程中必须调用这个重绘方法 invalidate()只能在ui线程调用
                    ProgressView.this.postInvalidate();
                }
            }
        }).start();
    }

总结

可以通过改变最后一步集合的遍历方法来改变进度条的方式,通过绘制时的角度正负来控制方向等等。源码Demo可以从这里下载:点此跳转Github

有问题和建议欢迎留言告知啦~~