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>
相关推荐
A133455519 分钟前
苹果安卓手机播放器推荐:2026无广告4K怎么选
android·智能手机
hunterandroid2 小时前
ContentProvider 跨进程数据共享实战
android·前端
天空之城--2 小时前
Android输入法子系统深度解析
android
天空之城--4 小时前
Android全链路性能优化:从原理到实践的终极指南
android·性能优化
Meteors.4 小时前
Android 性能优化:05.CPU优化
android·性能优化
石头猫灯5 小时前
一次 CMS 被黑实录:完整事件思路梳理
android·学习
zhonyu鱼5 小时前
Escrcpy:用电脑键盘鼠标操作安卓手机的跨平台投屏工具
android·计算机外设·电脑
千里马学框架5 小时前
安卓开机性能优化:如何安全高效地裁剪 SystemService
android·智能手机·framework·wms·手机·性能·车载
Android打工仔5 小时前
一次 Android 拍照后卡顿的 Perfetto 定位与优化实践
android·性能优化
OpenFDE开源桌面5 小时前
实操:如何将安卓 App与Linux系统应用级融合(附代码)
android·linux