Android之View 提升: 六 自定义进度条

本文档介绍如何在Android中创建自定义进度条,通过重写onSizeChanged,onDraw和onMeasure方法,实现数字随进度条移动的效果。代码示例展示了自定义数字绘制、颜色设置以及左右边框的绘制。同时,给出了MainActivity中如何调用和更新进度的示例。
摘要由CSDN通过智能技术生成

Android之View 提升: 六 自定义进度条

一 知识点

  1. 重写3个方法:onSizeChangedonDrawonMeasure,实现数字随着进度条移动
  2. 自定义数字,使用Paint进行数字的绘制

二 实现效果

在这里插入图片描述

三 实现代码

  1. view文件
package cn.study.myapplication;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.ProgressBar;

/**
 * @author zyy
 * @date 2021年07月20日 下午8:38
 */
public class MyProgressView extends ProgressBar {

    protected Paint mPaint = new Paint();
    protected int mTextColor = 0XFF008000;
    protected int mTextSize = 60;
    protected int mTextOffset = 60;
    protected int mLeftHeight = 5;
    protected int mLeftColor = 0XFF0000FF;
    protected int mRightHeight = 15;
    protected int mRightColor = 0XFFFF0000;
    protected int mRealWidth;
    protected boolean isDraw = true;


    public MyProgressView(Context context, AttributeSet attrs) {
        this(context,attrs,0);
    }

    public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setHorizontalScrollBarEnabled(true);
        mPaint.setTextSize(mTextSize);
        mPaint.setColor(mTextColor);
    }


    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int mMode = MeasureSpec.getMode(heightMeasureSpec);
        if(mMode!=MeasureSpec.EXACTLY){
            float mHeight = (mPaint.descent() + mPaint.ascent());
            int mExceptHeight = (int)(getPaddingTop()+getPaddingBottom()+Math.max(Math.max(mLeftHeight,mRightHeight),Math.abs(mHeight)));
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(mExceptHeight, MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        canvas.translate(getPaddingLeft(),getHeight()/2);
        boolean isNeed = false;
        float mRatio = getProgress() * 1.0f / getMax();
        float mPosx = (int)(mRealWidth * mRatio);
        String mText = String.valueOf(getProgress()) + "%";
        float mTextWidth = mPaint.measureText(mText);
        float mTextHeight = (mPaint.descent()+mPaint.ascent())/2;
        if(mPosx + mTextWidth > mRealWidth){
            mPosx = mRealWidth - mTextWidth;
            isNeed = true;
        }

        float mEndx = mPosx - mTextOffset / 2;
        if(mEndx > 0){
            mPaint.setColor(mLeftColor);
            mPaint.setStrokeWidth(mLeftHeight);
            canvas.drawLine(0,0,mEndx,0,mPaint);
        }

        if(isDraw){

            mPaint.setColor(mTextColor);
            canvas.drawText(mText,mPosx,-mTextHeight,mPaint);
        }

        if(!isNeed){
            float start = mPosx + mTextOffset/2 + mTextWidth;
            mPaint.setColor(mRightColor);
            mPaint.setStrokeWidth(mRightHeight);
            canvas.drawLine(start, 0 , mRealWidth, 0, mPaint);
        }

        super.onDraw(canvas);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mRealWidth = w-getPaddingRight() - getPaddingLeft();
    }
}

  1. MainActivity 中调用
public class MainActivity extends AppCompatActivity {

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

        MyProgressView myProgressView = findViewById(R.id.mprogress);
        int MAX_PROGRESS = 100;
        myProgressView.setMax(MAX_PROGRESS);
        new Thread(new Runnable() {
            @Override
            public void run() {
                int progress = 0;
                while(progress < MAX_PROGRESS){
                    try {
                        Thread.sleep(MAX_PROGRESS);
                        progress++;
                        myProgressView.incrementProgressBy(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}
  1. layout文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <cn.study.myapplication.MyProgressView
        android:layout_marginTop="300dp"
        android:layout_marginStart="20dp"
        android:layout_width="200dp"
        android:layout_height="30dp"
        android:id="@+id/mprogress"/>

</LinearLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值