Android自定义圆形进度条

本文介绍了如何使用自定义Drawable创建圆形进度条,包括继承View、重写draw方法绘制圆环以及通过实时更新进度值来调整进度条外观。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义圆形进度条

其实圆形进度条总体上来说是比较简单的,简单的步骤如下:

1、继承一个View或者Drawable,本教程选择Drawable

2、重写public void draw(Canvas canvas){...}函数,在该函数中画圆环,其中有一个参数progress用来指定画圆弧的角度。

3、在进行下载操作的controller中实时变更progress,并在setProgress方法中重绘。


源码:ZyCircularProgressDrawable

package com.example.ustc_zy.myapplication;

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Bundle;

/**
 * Created by ustc-zy on 15-10-28.
 */
public class ZyCircularProgressDrawable extends Drawable {

    public boolean isRunning = false;
    public static final String PROGRESS_PROPERTY="progress";
    public static final String RING_COLOR="ringColor";
    private float progress = 0;

    private int ringWidth;

    private int ringColor;
    private int ringBackgroundColor;
    private Paint paint;

    protected final RectF arcElements;

    private int max = 100;
    ZyCircularProgressDrawable(int ringWidth, int ringColor, int ringBackgroundColor){
        this.ringWidth = ringWidth;
        this.paint = new Paint();
        paint.setAntiAlias(true);
        this.ringColor = ringColor;
        this.ringBackgroundColor = ringBackgroundColor;

        arcElements = new RectF();
    }


    @Override
    public void draw(Canvas canvas) {
        final Rect bounds = getBounds();

        int size = Math.min(bounds.height(), bounds.width());
        float outerRadius = (size / 2) - (ringWidth / 2);
        float offsetX = (bounds.width() - outerRadius * 2) / 2;
        float offsetY = (bounds.height() - outerRadius * 2 ) / 2;

        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(1);
        paint.setColor(ringBackgroundColor);

        canvas.drawCircle(bounds.centerX(), bounds.centerY(), outerRadius, paint);

        int halfRingWidth = ringWidth / 2;
        float arcX0 = offsetX + halfRingWidth;
        float arcY0 = offsetY + halfRingWidth;
        float arcX = offsetX + outerRadius * 2 - halfRingWidth;
        float arcY = offsetY + outerRadius * 2 - halfRingWidth;

        paint.setColor(ringColor);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(ringWidth);
        paint.setStrokeCap(Paint.Cap.ROUND);
        arcElements.set(arcX0, arcY0, arcX, arcY);
//        if(indeterminate) {
//            canvas.drawArc(arcElements, progress, 90, false, paint);
//        }else{
//            canvas.drawArc(arcElements, 89, progress, false, paint);
//        }
        canvas.drawArc(arcElements,89, progress ,false, paint);
    }

    @Override
    public void setAlpha(int alpha) {
        paint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        paint.setColorFilter(colorFilter);
    }

    @Override
    public int getOpacity() {
        return 1-paint.getAlpha();
    }


    public void setProgress(float progress) {
//        if(indeterminate) {
//            this.progress = progress;
//        }else{
//            this.progress = PROGRESS_FACTOR * progress;
//        }
            this.progress = progress;
            invalidateSelf();
    }

    public void setRingColor(int ringColor){

        this.ringColor = ringColor;
        invalidateSelf();
    }

    private boolean indeterminate = false;

    public boolean isIndeterminate(){return indeterminate;}

    public void setIndeterminate(boolean indeterminate){this.indeterminate = indeterminate;}

}


MainActivity:

package com.example.ustc_zy.myapplication;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;


public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    ImageView imageView;
    Button button;
    ZyCircularProgressDrawable drawable;
    Animator currentAnimator;

    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(currentAnimator != null){
                currentAnimator.cancel();
            }
            switch (v.getId()){
                case R.id.imageView:
                    currentAnimator = prepareRingAnimation();
                    break;

            }
            currentAnimator.start();
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @Override
    protected void onResume(){
        super.onResume();
        imageView = (ImageView)findViewById(R.id.imageView);
        button = (Button)findViewById(R.id.button);
        drawable = new ZyCircularProgressDrawable(getResources().getDimensionPixelSize(R.dimen.ringWidth)
                ,getResources().getColor(android.R.color.holo_blue_bright)
                ,getResources().getColor(android.R.color.darker_gray));
        imageView.setImageDrawable(drawable);
        imageView.setOnClickListener(listener);

        button.setOnClickListener(this);
    }

    public void downloadFile(){

        Thread downloadThread = new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                while(i < 360){
                    i++;
                    try {
                        Thread.sleep(500);
                        Message msg = new Message();
                        msg.arg1 = i;
                        handler.sendMessage(msg);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }

            }
        });
        downloadThread.start();
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg){
            int progress = msg.arg1;
            drawable.setProgress((float) progress);
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private Animator prepareRingAnimation() {
         AnimatorSet animator = new AnimatorSet();

        ObjectAnimator progressAnimation = ObjectAnimator.ofFloat(drawable
                , ZyCircularProgressDrawable.PROGRESS_PROPERTY, 0f, 1f);
        progressAnimation.setDuration(3600);
        progressAnimation.setInterpolator(new AccelerateDecelerateInterpolator());

        ObjectAnimator coloeAnimator = ObjectAnimator.ofInt(drawable
                , ZyCircularProgressDrawable.RING_COLOR
                ,getResources().getColor(android.R.color.holo_green_dark),
                getResources().getColor(android.R.color.holo_blue_bright));
        coloeAnimator.setEvaluator(new ArgbEvaluator());
        coloeAnimator.setDuration(3600);

        animator.playTogether(progressAnimation, coloeAnimator);
        return animator;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:

                downloadFile();
                break;
        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值