Android自定义View之三种流行进度条的写法

概述:

利用自定义View的onDraw()方法,可以绘制很多种图形,进度框只是其中之一。

Demo

这是一个模拟下载的demo。

自中央逐渐充满型圆形进度框

这里写图片描述

demo1

public class FirstProgressView extends View{

    private int width;
    private int height;

    private int progress;
    private int maxProgress = 100;
    private Paint mPaintBackGround;
    private Paint mPaintCurrent;
    private Paint mPaintText;

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
        invalidate();
    }

    public int getMaxProgress() {
        return maxProgress;
    }

    public void setMaxProgress(int maxProgress) {
        this.maxProgress = maxProgress;
    }

    public FirstProgressView(Context context) {
        super(context);
    }

    public FirstProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaintBackGround = new Paint();//新定义一个画笔,用来画背景
        mPaintBackGround.setColor(Color.GRAY);//设置画笔颜色
        mPaintBackGround.setAntiAlias(true);//设置为true,代表抗锯齿

        mPaintCurrent = new Paint();//用于画进度图
        mPaintCurrent.setColor(Color.GREEN);
        mPaintCurrent.setAntiAlias(true);

        mPaintText = new Paint();//用来画文本的画笔
        mPaintText.setColor(Color.BLACK);
        mPaintText.setAntiAlias(true);
        mPaintText.setTextAlign(Paint.Align.CENTER);//设置文本排布方式:正中央
        mPaintText.setTextSize(50);//设置文本大小,这里为50xp
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //左起:圆心x坐标,圆心y坐标,半径,Paint对象(画笔)
        canvas.drawCircle(width / 2, height / 2, 400, mPaintBackGround);
        canvas.drawCircle(width/2,height/2,progress*400f/maxProgress,mPaintCurrent);
        //左起:文本内容,起始位置x坐标,起始位置y坐标,画笔
        canvas.drawText(progress*100f/maxProgress+"%",width / 2, height / 2,mPaintText);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //该View布局宽
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        //该View布局高
        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        //设定本View的大小的方法
        setMeasuredDimension(width, height);
    }
}

水箱型注水式进度框

这里写图片描述

demo2

public class SecondProgressView extends View {

    private int width;
    private int height;

    private int progress;
    private int maxProgress = 100;
    private Paint mPaintBackGround;
    private Paint mPaintCurrent;
    private Paint mPaintText;

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
        invalidate();
    }

    public int getMaxProgress() {
        return maxProgress;
    }

    public void setMaxProgress(int maxProgress) {
        this.maxProgress = maxProgress;
    }

    public SecondProgressView(Context context) {
        super(context);
    }

    public SecondProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaintBackGround = new Paint();
        mPaintBackGround.setColor(Color.GRAY);
        mPaintBackGround.setStyle(Paint.Style.STROKE);
        mPaintBackGround.setStrokeWidth(20);
        mPaintBackGround.setAntiAlias(true);

        mPaintCurrent = new Paint();
        mPaintCurrent.setColor(Color.BLUE);
        mPaintCurrent.setAntiAlias(true);

        mPaintText = new Paint();
        mPaintText.setColor(Color.BLACK);
        mPaintText.setAntiAlias(true);
        mPaintText.setTextAlign(Paint.Align.CENTER);
        mPaintText.setTextSize(50);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawRect(width / 2 - 200, height / 2 - 200, width / 2 + 200, height / 2 + 200, mPaintBackGround);
        canvas.drawRect(width/2-190,height/2-190+(380-progress*380f/maxProgress),width/2+190,height/2+190,mPaintCurrent);
        canvas.drawText(progress*100f/maxProgress+"%",width / 2, height / 2,mPaintText);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);
    }
}

圆圈式弧形进度框:

这里写图片描述

demo3:

public class ThirdProgressView extends View {

    private int width;
    private int height;

    private int progress;
    private int maxProgress = 100;
    private Paint mPaintBackGround;
    private Paint mPaintCurrent;
    private Paint mPaintText;

    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
        invalidate();
    }

    public int getMaxProgress() {
        return maxProgress;
    }

    public void setMaxProgress(int maxProgress) {
        this.maxProgress = maxProgress;
    }

    public ThirdProgressView(Context context) {
        super(context);
    }

    public ThirdProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaintBackGround = new Paint();
        mPaintBackGround.setColor(Color.GRAY);
        mPaintBackGround.setStrokeWidth(60);
        mPaintBackGround.setStyle(Paint.Style.STROKE);
        mPaintBackGround.setAntiAlias(true);

        mPaintCurrent = new Paint();
        mPaintCurrent.setColor(Color.GREEN);
        mPaintCurrent.setStrokeWidth(60);
        mPaintCurrent.setStyle(Paint.Style.STROKE);
        mPaintCurrent.setAntiAlias(true);

        mPaintText = new Paint();
        mPaintText.setColor(Color.BLACK);
        mPaintText.setAntiAlias(true);
        mPaintText.setTextAlign(Paint.Align.CENTER);
        mPaintText.setTextSize(50);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawCircle(width / 2, height / 2, 400, mPaintBackGround);
        RectF oval = new RectF(width/2-400,height/2-400,width/2+400,height/2+400);
        //左起分别是RectF对象,起始角度,终止角度,是否显示扇边(如果为true画出的是一个扇形),Paint对象
        canvas.drawArc(oval,0,progress*360f/maxProgress,false,mPaintCurrent);
        canvas.drawText(progress*100f/maxProgress+"%",width / 2, height / 2,mPaintText);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);
    }
}

需要在布局文件中加载自定义View,这里随便加载一个作示范(自定义View都这么加载):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start Download"/>

    <com.example.administrator.selfdefinedview.widget.ThirdProgressView
        android:id="@+id/progress_view_first"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

主活动的中自定义View也需要声明和findViewById,这里写的是一个模拟下载的小demo,加载的是第三种自定义View,其他的自定义View加载方式完全一样。

public class MainActivity extends Activity {
    private int progress;
    private Button mButtonStart;
    private ThirdProgressView mProgressView;

    private static final int DOWNLOAD_UPDATE = 0x99;
    //模拟下载
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //处理msg
            switch (msg.what) {
                case DOWNLOAD_UPDATE:
                    progress++;
                    if (progress <= 100) {
                        mProgressView.setProgress(progress);
                        sendEmptyMessageDelayed(DOWNLOAD_UPDATE, 100);//每隔100毫秒发送一次handler
                    }
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButtonStart = (Button) findViewById(R.id.button_start);
        mProgressView = (ThirdProgressView) findViewById(R.id.progress_view_first);

        mButtonStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //向handler发送一个延时空消息,1000毫秒后发送
                mHandler.sendEmptyMessageDelayed(DOWNLOAD_UPDATE, 1000);
            }
        });

    }
}

我们猿类工作压力大,很需要有自己的乐趣,于是乎,我开通了音乐人账号,以后的作品将会上传到我的音乐人小站上。如果这篇博客帮助到您,希望您能多关注,支持,鼓励我将创作进行下去,同时也祝你能在工作和生活乐趣两发面都能出彩!

网易云音乐人,直接打开客户端搜索音乐人 “星河河”

豆瓣音乐人地址:https://site.douban.com/chuxinghe/ 星河河

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值