Android 下载进度条HorizontalProgressView 基础版

一个最基础的自定义View 水平横向进度条,只有圆角、下载进度控制;可二次定制度高;

核心代码:

复制代码
    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        int mW = getMeasuredWidth();
        int mH = getMeasuredHeight();
        Log.i(TAG, "onDraw: "+mW +"-" +mH);

        //先剪切出进度条的形状、主要是圆角
        Path path = new Path();
        path.addRoundRect(0,0,mW,mH ,radius,radius, Path.Direction.CCW);
        canvas.clipPath(path);

        //画背景色
        paint.setColor(backgroundColor);
        Rect rectBg = new Rect(0,0,mW,mH);
        canvas.drawRect(rectBg,paint);

        //画进度条颜色
        double ratio  = Math.min(progress / max , 1.00) ;
//        canvas.clipRect(0, 0, (int) (mW*ratio), mH);
//        canvas.drawColor(loadingColor);
        paint.setColor(loadingColor);
        Rect rect = new Rect(0, 0,  (int)(mW * ratio), mH);
        canvas.drawRect(rect,paint);
    }

全部代码:

复制代码
package com.cuichen.mytestdemo.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.cuichen.mytestdemo.R;

public class HorizontalProgressView extends View {
    private final String TAG = HorizontalProgressView.class.getSimpleName();
    public HorizontalProgressView(Context context) {
        super(context);
    }

    public HorizontalProgressView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs);
    }

    public HorizontalProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(attrs);
    }

    public HorizontalProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initAttrs(attrs);
    }

    private void initAttrs( @Nullable AttributeSet attrs){
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs , R.styleable.HorizontalProgress);
        try{
            backgroundColor = typedArray.getColor(R.styleable.HorizontalProgress_backgroundColor , Color.parseColor("#FF03DAC5"));
            loadingColor = typedArray.getColor(R.styleable.HorizontalProgress_progressColor ,Color.parseColor("#FF018786"));
            radius = (int) typedArray.getDimension(R.styleable.HorizontalProgress_radiusDp , 0);
            max = typedArray.getInt(R.styleable.HorizontalProgress_max , 100);
            progress = typedArray.getInt(R.styleable.HorizontalProgress_progress , 50);
        }catch (Exception e){
            typedArray.recycle();
        }

    }


    private int radius = 18;
    private float progress = 0f;
    private float max = 100f;
    private int backgroundColor;
    private int loadingColor;

    final int DEFAULT_HEIGHT_DP = 36;

    Paint paint;
    void init(){
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);

    }

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


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.i(TAG, "onMeasure: ");
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
        int height = 0;
        switch (heightSpecMode){
            case MeasureSpec.AT_MOST:
                height = dp2px(DEFAULT_HEIGHT_DP);
                break;
            case MeasureSpec.EXACTLY:
            case MeasureSpec.UNSPECIFIED:
                height = heightSpecSize;
                break;
        }
        setMeasuredDimension(widthSpecSize, height);

        if(paint == null) {
            init();
        }
    }

    //RectF
    //left:左边坐标;在绘制中常表示为起点的Y轴坐标
    //top:上边左边;在绘制中常表示为起点的X轴坐标
    //right:右边坐标;在绘制中常表示为终点的X轴坐标
    //bottom:下边坐标;在绘制中常表示为终点的Y轴坐标
    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        int mW = getMeasuredWidth();
        int mH = getMeasuredHeight();
        Log.i(TAG, "onDraw: "+mW +"-" +mH);

        //先剪切出进度条的形状、主要是圆角
        Path path = new Path();
        path.addRoundRect(0,0,mW,mH ,radius,radius, Path.Direction.CCW);
        canvas.clipPath(path);

        //画背景色
        paint.setColor(backgroundColor);
        Rect rectBg = new Rect(0,0,mW,mH);
        canvas.drawRect(rectBg,paint);

        //画进度条颜色
        double ratio  = Math.min(progress / max , 1.00) ;
//        canvas.clipRect(0, 0, (int) (mW*ratio), mH);
//        canvas.drawColor(loadingColor);
        paint.setColor(loadingColor);
        Rect rect = new Rect(0, 0,  (int)(mW * ratio), mH);
        canvas.drawRect(rect,paint);
    }
    private int dp2px(int dp){
        float density = getContext().getResources().getDisplayMetrics().density;
        return (int) (dp * density);
    }
}

    <declare-styleable name="HorizontalProgress">
        <attr name="backgroundColor" format="color"/>
        <attr name="progressColor" format="color"/>
        <attr name="radiusDp" format="dimension"/>
        <attr name="max" format="integer"/>
        <attr name="progress" format="integer"/>
    </declare-styleable>
相关推荐
阿巴斯甜20 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker21 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95271 天前
Andorid Google 登录接入文档
android
黄林晴1 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿2 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android