如何实现一个圆弧倒计时进度条


一、前言

最近的项目中,需要实现一个圆弧形倒计时进度条,对于本来 css 知识薄弱的我当场就懵逼,脑海里总是不断思考如何实现,不幸的是脑袋里没能蹦出半个想法。然后立马百度查看网上是否有相似的解决方案,百度下来初步知道如何来实现了,那我们就一步一步从 0 到有开始这段旅程。

首先展示一下最终的成果,最终效果图如下:

实现要点:浅色圆弧需要分成左右两边,左右两边都需要用一个同心原来实现,亮色圆弧也需要左右分开,各自用一个同心圆来实现。让我们开始吧!

二、实现步骤

添加容器

让整个容器是 position: fixed 方便可以在整个页面上随意放置 html 代码:

<div class="task-container"></div>

css 代码:

.task-container {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    width: 65px;
    height: 65px;
    display: flex;
    justify-content: center;
    align-items: center;
}

画底盘

加点阴影,让它看起来有点立体的感觉 html 代码:

<div class="task-container">
    <div class="task-cicle"></div>
</div>

css 代码:

.task-container {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    width: 65px;
    height: 65px;
    display: flex;
    justify-content: center;
    align-items: center;
 
    .task-cicle {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 53px;
        height: 53px;
        border-radius: 50%;
        background: #FFFFFF;
        box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.05);
    }
}

效果:

重点来了,接下来实现圆弧

我们先画右圆弧,我们用右半边矩形来实现,右半圆只设置上方和右边的边框颜色 html 代码:

<div class="task-container">
    <div class="task-cicle">
        <div class="task-inner">
            <div class="right-cicle">
                <div class="cicle-progress cicle1-inner"></div>
            </div>
        </div>
    </div>
</div>

css 代码:

.task-container {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    width: 65px;
    height: 65px;
    display: flex;
    justify-content: center;
    align-items: center;


    .task-cicle {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 53px;
        height: 53px;
        border-radius: 50%;
        background: #FFFFFF;
        box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.05);
    }

    .task-inner {
        position: relative;
        width: 46px;
        height: 46px;
    }

    .right-cicle {
        width: 23px;
        height: 46px;
        position: absolute;
        top: 0;
        right: 0;
        overflow: hidden;
    }

    .cicle-progress {
        position: absolute;
        top: 0;
        width: 46px;
        height: 46px;
        border: 3px solid transparent;
        box-sizing: border-box;
        border-radius: 50%;
    }

    .cicle1-inner {
        left: -23px;
        border-right: 3px solid #e0e0e0;
        border-top: 3px solid #e0e0e0;
        transform: rotate(-15deg);
    }
}

right-cicle 需要设置 overflow: hidden;对子元素超出的部分进行裁剪。cicle1-inner 中的旋转-15 度,其实可以根据设计稿来调整你需要展示的弧度 如果父节点,没有进行裁剪,右半圆就会延伸到左边

裁剪之后的效果

画左边的弧

接下来根据同样的原理画左边的弧。左边的圆,只设置上方和左边的边框颜色 html 代码:

<div class="task-container">
    <div class="task-cicle">
        <div class="task-inner">
            <div class="right-cicle">
                <div class="cicle-progress cicle1-inner"></div>
            </div>
            <div class="left-cicle">
                <div class="cicle-progress cicle2-inner"></div>
            </div>
        </div>
    </div>
</div>

css 代码:

.left-cicle {
    width: 23px;
    height: 46px;
    position: absolute;
    top: 0;
    left: 0;
    overflow: hidden;
}

.cicle2-inner {
    left: 0;
    border-left: 3px solid #e0e0e0;
    border-top: 3px solid #e0e0e0;
    transform: rotate(15deg);
}

效果如下:

ok,圆弧的基本轮廓已经完成,接下来实现亮色进度条,进度条也是分左右边各自实现

画右半边进度条

右半边圆只设置上方和右边的边框颜色 html 代码:

<div class="task-container">
    <div class="task-cicle">
        <div class="task-inner">
            <div class="right-cicle">
                <div class="cicle-progress cicle1-inner"></div>
            </div>
            <div class="left-cicle">
                <div class="cicle-progress cicle2-inner"></div>
            </div>
            <div class="right-cicle">
                <div class="cicle-progress cicle3-inner" id="rightCicle"></div>
            </div>
        </div>
    </div>
</div>

css 代码:

.cicle3-inner {
    left: -23px;
    border-right: 3px solid #feca02;
    border-top: 3px solid #feca02;
    transform: rotate(-135deg);
}

效果如下:为什么是旋转-135 度?进度条是从左边蔓延到右边的,让亮色进度条旋转到左右两边的临界点,也就是初始角度是-135 度,随着时间推移增加旋转角度,进度条就蔓延到右边了转到哪个角度为止呢?转到亮色边框和右边灰色边框重合,也就是-15 度,那么右边亮色进度条的旋转角度范围就是-135 度到-15 度,共 120 度的。右半边进度条已经完成,初始角度是-135 度,随着时间的推移,慢慢旋转到-15 度的位置

画左半边的进度条

左半圆只设置上方和左边的边框颜色 html 代码:

<div class="task-container">
    <div class="task-cicle">
        <div class="task-inner">
            <div class="right-cicle">
                <div class="cicle-progress cicle1-inner"></div>
            </div>
            <div class="left-cicle">
                <div class="cicle-progress cicle2-inner"></div>
            </div>
            <div class="right-cicle">
                <div class="cicle-progress cicle3-inner" id="rightCicle"></div>
            </div>
            <div class="left-cicle">
                <div class="cicle-progress cicle4-inner" id="leftCicle"></div>
            </div>
        </div>
    </div>
</div>

css 代码:

.cicle4-inner {
    left: 0;
    border-left: 3px solid #feca02;
    border-top: 3px solid #feca02;
    transform: rotate(195deg);
}

效果如下(为了演示,父节点为设置了 overflow: inherit;不裁剪,能更清楚来龙去脉):

为什么要旋转 195 度?进度条是从左边开始由无到有的,我们让亮色进度条旋转到左边灰色圆弧起始点的临界点位置,随着时间的推移增加旋转角度。左边进度条要转 120 度,所以左边进度条旋转角度范围:195 到 315 度 我们把父节点的 overflow 设置回原来的 hidden,对子节点超出的部分进行裁剪。

what?裁剪之后还露出了一个小尾巴,如何把这个小尾巴给掩盖掉?这时候我们需要在左边再画一个同心圆来遮盖掉它

画遮盖圆

注意:遮罩圆边框宽度要比左边亮色进度条圆的边框宽度要大,不然会遮盖不完全,会出现金色余晖,且要和亮色进度条是同心圆 html 代码:

<div class="task-container">
    <div class="task-cicle">
        <div class="task-inner">
            <div class="right-cicle">
                <div class="cicle-progress cicle1-inner"></div>
            </div>
            <div class="left-cicle">
                <div class="cicle-progress cicle2-inner"></div>
            </div>
            <div class="right-cicle">
                <div class="cicle-progress cicle3-inner" id="rightCicle"></div>
            </div>
            <div class="left-cicle">
                <div class="cicle-progress cicle4-inner" id="leftCicle"></div>
            </div>
            <div class="left-cicle">
                <div class="mask-inner"></div>
            </div>
        </div>
    </div>
</div>

css 代码(为了展示遮罩圆是完全覆盖的,我把父节点的 overflow: inherit;不裁剪,圆的边框颜色设置为蓝色):

.mask-inner {
    position: absolute;
    left: 0;
    top: 0;
    width: 39px;
    height: 39px;
    // border: 4px solid transparent;
    border: 4px solid blue;
    border-radius: 50%;
    // border-left: 4px solid #FFFFFF;
    // border-top: 4px solid #FFFFFF;
    // transform: rotate(195deg);
}

看,我们的遮罩圆已经完全遮罩了其他圆,遮盖圆和左边进度条圆一样,都是旋转 195 度,只设置上方和左边的边框颜色,边框颜色是和底盘颜色一样,我们把父节点 overflow 设置为 hidden 裁剪 css 代码:

.mask-inner {
    position: absolute;
    left: 0;
    top: 0;
    width: 39px;
    height: 39px;
    border: 4px solid transparent;
    border-radius: 50%;
    border-left: 4px solid blue;
    border-top: 4px solid blue;
    transform: rotate(197deg);
}

蓝色部分就是我们的小尾巴的位置,我们用白色替换蓝色边框

.mask-inner {
    position: absolute;
    left: 0;
    top: 0;
    width: 39px;
    height: 39px;
    border: 4px solid transparent;
    border-radius: 50%;
    border-left: 4px solid #FFFFFF;
    border-top: 4px solid #FFFFFFl
    transform: rotate(197deg);
}

效果:

哇,看看,小尾巴已经不见了。如果遮盖圆和左边亮色进度条设置一样的边框大小,会出现金色边

好吧,样式方面已经基本完成,其他点缀的样式就不在这里列出了,可以看看下面的源码。要让进度条动起来,需要通过 js 来操作,js 里的源码我已经写了比较清楚的注释,方便理解。html 代码:

<div class="task-container">
    <div class="task-cicle">
        <div class="task-inner">
            <div class="right-cicle">
                <div class="cicle-progress cicle1-inner"></div>
            </div>
            <div class="left-cicle">
                <div class="cicle-progress cicle2-inner"></div>
            </div>
            <div class="right-cicle">
                <div class="cicle-progress cicle3-inner" id="rightCicle"></div>
            </div>
            <div class="left-cicle">
                <div class="cicle-progress cicle4-inner" id="leftCicle"></div>
            </div>
            <div class="left-cicle">
                <div class="mask-inner"></div>
            </div>
            <div class="inner">
                <img src="https://img12.360buyimg.com/img/jfs/t1/150018/30/1001/2042/5eec2f8eEfd3c853a/e7982308423ce71a.png" alt="" srcset="">
                <div class="water-count">10</div>
            </div>
        </div>
        <div class="task-bottom">
            <div class="task-btn" id="time"></div>
        </div>
    </div>
</div>


<script>
    const rightCicle = document.getElementById('rightCicle');
    const leftCicle = document.getElementById('leftCicle');
    const timeDom = document.getElementById('time');
    let isStop = false;
    let timer;
    const totalTime = 10; // 总时间
    const halfTime = totalTime / 2; // 总时间的一半
    const initRightDeg = -135; // 右半边进度条初始角度
    const initLeftDeg = 195; // 左半边进度条初始角度
    const halfCicle = 120; // 左右连边各要转的总角度
    const perDeg = 120 / halfTime; // 每秒转的角度
    let inittime = 10;
    let begTime; // 倒计时开始时间戳
    let stopTime; // 倒计时停止时间戳

    function run() {
        const time = inittime;
        let animation;
        if (time > halfTime) {
            // 左半边还没转完
            // 左半边:动画的初始角度=左半边进度条初始角度+已经转的角度,最终角度=初始角度+120 度,动画持续时间=左半边还剩需要转的时间
            // 右半边:动画的初始角度=右半边进度条初始角度,最终角度=初始角度+120 度,动画持续时间=一半的时间,动画延迟=左半边还剩需要转的时间
            animation = `
                @keyframes task-left {
                    0% {
                        transform: rotate(${initLeftDeg + (totalTime - time) * perDeg}deg);
                    }
                    100% {
                        transform: rotate(${initLeftDeg + halfCicle}deg);
                    }
                }
                .task-left {
                    animation-name: task-left;
                    animation-duration: ${time - halfTime}s;
                    animation-timing-function: linear;
                    animation-delay: 0s;
                    animation-fill-mode: forwards;
                    animation-direction: normal;
                    animation-iteration-count: 1;
                }
                @keyframes task-right {
                    0% {
                        transform: rotate(${initRightDeg}deg);
                    }
                    100% {
                        transform: rotate(${initRightDeg + halfCicle}deg);
                    }
                }
                .task-right {
                    animation-name: task-right;
                    animation-duration: ${halfTime}s;
                    animation-timing-function: linear;
                    animation-delay: ${time - halfTime}s;
                    animation-fill-mode: forwards;
                    animation-direction: normal;
                    animation-iteration-count: 1;
                }
            `;
        } else {
            // 左半边已经转完
            // 左半边动画:起始帧和重点帧都=左半边进度条初始角度+120 度
            // 右半边动画:动画的初始角度=右半边进度条初始角度+右半边已经角度,最终角度=初始角度+120 度,动画持续时间=剩余时间
            animation = `
                @keyframes task-left {
                    0% {
                        transform: rotate(${initLeftDeg + halfCicle}deg);
                    }
                    100% {
                        transform: rotate(${initLeftDeg + halfCicle}deg);
                    }
                }
                .task-left {
                    animation-name: task-left;
                    animation-duration: 0s;
                    animation-timing-function: linear;
                    animation-delay: 0s;
                    animation-fill-mode: forwards;
                    animation-direction: normal;
                    animation-iteration-count: 1;
                }
                @keyframes task-right {
                    0% {
                        transform: rotate(${initRightDeg + (halfTime - time) * perDeg}deg);
                    }
                    100% {
                        transform: rotate(${initRightDeg + halfCicle}deg);
                    }
                }
                .task-right {
                    animation-name: task-right;
                    animation-duration: ${time}s;
                    animation-timing-function: linear;
                    animation-delay: 0s;
                    animation-fill-mode: forwards;
                    animation-direction: normal;
                    animation-iteration-count: 1;
                }
            `;
        }
        // 增加动画暂停和开始类
        animation += `.stop {animation-play-state: paused;} .run {animation-play-state: running;}`
        const styleDom = document.createElement('style');
        styleDom.type = 'text/css';
        styleDom.innerHTML = animation;
        document.getElementsByTagName('head').item(0).appendChild(styleDom);
        leftCicle.classList.add('task-left');
        rightCicle.classList.add('task-right');
        begTime = Date.now();
        countDown();
    }

    function countDown() {
        if (begTime && stopTime) {
            // 从 1 秒到 1.6 秒后暂停,动画一直在走,而倒计时因为未到 2 秒,定时器就清除了,下次还是会从 1 开始计时,
            // 这就会导致倒计时和动画的不同步,之类稍微校正一下,如果结束时间和开始时间取余数大于 500,就把倒计时-1 秒
            const runtime = stopTime - begTime;
            console.log(runtime % 1000);
            if (runtime % 1000 > 500) {
                inittime -= 1;
            }
        }
        begTime = Date.now();
        timeDom.innerText = `${inittime}秒后获得 `;
        timer = setInterval(() => {
            inittime -= 1;
            timeDom.innerText = `${inittime}秒后获得 `;
            if (inittime <= 0) {
                clearInterval(timer);
            }
        }, 1000);
    }
    // 点击可暂停倒计时和动画
    timeDom.addEventListener('click', () => {
        if (isStop) {
            isStop = false;
            countDown();
            leftCicle.classList.remove('stop');
            leftCicle.classList.add('run');
            rightCicle.classList.remove('stop');
            rightCicle.classList.add('run');
        } else {
            stopTime = Date.now();
            isStop = true;
            clearInterval(timer);
            leftCicle.classList.remove('run');
            leftCicle.classList.add('stop');
            rightCicle.classList.remove('run');
            rightCicle.classList.add('stop');
        }
    }, false);

    run();
</script>

css 代码:

.task-container {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    width: 65px;
    height: 65px;
    display: flex;
    justify-content: center;
    align-items: center;


    .task-cicle {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 53px;
        height: 53px;
        border-radius: 50%;
        background: #FFFFFF;
        box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.05);
    }

    .task-inner {
        position: relative;
        width: 46px;
        height: 46px;
    }

    .right-cicle {
        width: 23px;
        height: 46px;
        position: absolute;
        top: 0;
        right: 0;
        overflow: hidden;
    }

    .cicle-progress {
        position: absolute;
        top: 0;
        width: 46px;
        height: 46px;
        border: 3px solid transparent;
        box-sizing: border-box;
        border-radius: 50%;
    }

    .cicle1-inner {
        left: -23px;
        border-right: 3px solid #e0e0e0;
        border-top: 3px solid #e0e0e0;
        transform: rotate(-15deg);
    }

    .left-cicle {
        width: 23px;
        height: 46px;
        position: absolute;
        top: 0;
        left: 0;
        overflow: hidden;
    }

    .cicle2-inner {
        left: 0;
        border-left: 3px solid #e0e0e0;
        border-top: 3px solid #e0e0e0;
        transform: rotate(15deg);
    }

    .cicle3-inner {
        left: -23px;
        border-right: 3px solid #feca02;
        border-top: 3px solid #feca02;
        transform: rotate(-135deg);
    }

    .cicle4-inner {
        left: 0;
        border-left: 3px solid #feca02;
        border-top: 3px solid #feca02;
        transform: rotate(195deg);
    }

    .mask-inner {
        position: absolute;
        left: 0;
        top: 0;
        width: 39px;
        height: 39px;
        border: 4px solid transparent;
        border-radius: 50%;
        border-left: 4px solid #FFFFFF;
        border-top: 4px solid #FFFFFF;
        transform: rotate(195deg);
    }

    .inner {
        position: absolute;
        left: 0;
        top: -2px;
        right: 0;
        bottom: 0;
        width: 22px;
        height: 26px;
        margin: auto;

        img {
            width: 100%;
            height: 100%;
        }
    }

    .water-count {
        position: absolute;
        top: 8px;
        left: 50%;
        transform: translateX(-50%);
        font-family: "JDZhengHei-01-Regular";
        font-size: 12px;
        color: #FFFFFF;
    }

    .task-bottom {
        display: flex;
        justify-content: center;
        align-items: center;
        position: absolute;
        width: 60px;
        height: 15px;
        left: 50%;
        transform: translateX(-50%);
        bottom: 2px;
    }

    .task-btn {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 15px;
        border-radius: 7px;
        background-image: linear-gradient(-45deg, #FEB402 0%, #FF8407 100%);
        font-size: 8px;
        color: #FFFFFF;
        line-height: 15px;
        padding: 0 4px;
    }
}

三、总结

浅色圆弧和亮色进度条的实现比较绕,一眼看过去不太好理解,我们可以把每一步拆分开。4 个圆弧的实现,父节点都进行了裁剪,裁剪之后很难看出子元素原本的样子,我们可以先把裁剪去掉,看看未裁剪时,各个圆的表现。

最后

  • 欢迎加我微信(winty230),拉你进技术群,长期交流学习...

  • 欢迎关注「前端Q」,认真学前端,做个专业的技术人...

点个在看支持我吧

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
package com.example.task; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; public class CircleProgressBar extends View { private int maxProgress = 100; private int progress = 10; private int progressStrokeWidth = 20; // 画圆所在的距形区域 RectF oval; Paint paint; public CircleProgressBar(Context context, AttributeSet attrs) { super(context, attrs); // TODO 自动生成的构造函数存根 oval = new RectF(); paint = new Paint(); } @Override protected void onDraw(Canvas canvas) { // TODO 自动生成的方法存根 super.onDraw(canvas); int width = this.getWidth(); int height = this.getHeight(); if (width != height) { int min = Math.min(width, height); width = min; height = min; } paint.setAntiAlias(true); // 设置画笔为抗锯齿 paint.setColor(0xFFE2E2E2); // 设置画笔颜色 canvas.drawColor(Color.TRANSPARENT); // 白色背景 paint.setStrokeWidth(progressStrokeWidth); // 线宽 paint.setStyle(Style.STROKE); oval.left = progressStrokeWidth / 2; // 左上角x oval.top = progressStrokeWidth / 2; // 左上角y oval.right = width - progressStrokeWidth / 2; // 左下角x oval.bottom = height - progressStrokeWidth / 2; // 右下角y canvas.drawArc(oval, -90, 360, false, paint); // 绘制白色圆圈,即进度条背景 // paint.setColor(Color.rgb(0x57, 0x87, 0xb6)); paint.setColor(0xFFFF4700); canvas.drawArc(oval, -90, ((float) progress / maxProgress) * 360, false, paint); // 绘制进度圆弧,这里是蓝色 paint.setStrokeWidth(1); String text = progress + "分"; int textHeight = height / 4; paint.setTextSize(textHeight); int textWidth = (int) paint.measureText(text, 0, text.length()); paint.setStyle(Style.FILL); // canvas.drawText(text, width / 2 - textWidth / 2, height / 2 // + textHeight / 2, paint); } public int getMaxProgress() { return maxProgress; } public void setMaxProgress(int maxProgress) { this.maxProgress = maxProgress; } public void setProgress(int progress) { this.progress = progress; this.invalidate(); } /** * 非UI线程调用 */ public void setProgressNotInUiThread(int progress) { this.progress = progress; this.postInvalidate(); } } 上面的代码就是画两个圆弧 package com.example.task; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; public class MainActivity extends Activity { CircleProgressBar completedView1; CircleProgressBar completedView2; CircleProgressBar completedView3; CircleProgressBar completedView4; CircleProgressBar completedView5; CircleProgressBar completedView6; CircleProgressBar completedView7; CircleProgressBar completedView8; CircleProgressBar completedView9; CircleProgressBar completedView10; CircleProgressBar completedView11; CircleProgressBar completedView12; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); completedView1 = (CircleProgressBar) findViewById(R.id.circleProgressBar1); completedView2 = (CircleProgressBar) findViewById(R.id.circleProgressBar2); completedView3 = (CircleProgressBar) findViewById(R.id.circleProgressBar3); completedView4 = (CircleProgressBar) findViewById(R.id.circleProgressBar4); completedView5 = (CircleProgressBar) findViewById(R.id.circleProgressBar5); completedView6 = (CircleProgressBar) findViewById(R.id.circleProgressBar6); completedView7 = (CircleProgressBar) findViewById(R.id.circleProgressBar7); completedView8 = (CircleProgressBar) findViewById(R.id.circleProgressBar8); completedView9 = (CircleProgressBar) findViewById(R.id.circleProgressBar9); completedView10 = (CircleProgressBar) findViewById(R.id.circleProgressBar10); completedView11 = (CircleProgressBar) findViewById(R.id.circleProgressBar11); completedView12 = (CircleProgressBar) findViewById(R.id.circleProgressBar12); this.findViewById(R.id.button_show).setOnClickListener( new OnClickListener() { private int i2 = 40; @Override public void onClick(View v) { // completedView1.setProgressNotInUiThread(i2 % 100); // completedView2.setProgressNotInUiThread(i2 % 100); // completedView3.setProgressNotInUiThread(i2 % 100); // completedView4.setProgressNotInUiThread(i2 % 100); // completedView5.setProgressNotInUiThread(i2 % 100); // completedView6.setProgressNotInUiThread(i2 % 100); // completedView7.setProgressNotInUiThread(i2 % 100); // completedView8.setProgressNotInUiThread(i2 % 100); // completedView9.setProgressNotInUiThread(i2 % 100); // completedView10.setProgressNotInUiThread(i2 % 100); // completedView11.setProgressNotInUiThread(i2 % 100); // completedView12.setProgressNotInUiThread(i2 % 100); // i2 += 10; new Thread() { public void run() { int i = 0; while (i <= i2) { completedView1.setProgressNotInUiThread(i); completedView2.setProgressNotInUiThread(i); completedView3.setProgressNotInUiThread(i); completedView4.setProgressNotInUiThread(i); completedView5.setProgressNotInUiThread(i); completedView6.setProgressNotInUiThread(i); completedView7.setProgressNotInUiThread(i); completedView8.setProgressNotInUiThread(i); completedView9.setProgressNotInUiThread(i); completedView10.setProgressNotInUiThread(i); completedView11.setProgressNotInUiThread(i); completedView12.setProgressNotInUiThread(i); i++; try { sleep(10); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } }.start(); i2 += 10; } }); } } 上面的主活动界面使用线程画图

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值