文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android自定义分段式进度条

2024-04-02 19:55

关注

安卓自定义分段式的进度条,供大家参考,具体内容如下

前一段时间公司新项目接到一个新需求,其中界面需要用到一个分段式的进度条,找了半天没有发现类似的控件,于是决定自己写一个,话不多说,上代码


package com.djt.aienglish.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.djt.aienglish.R;


public class SegmentProgressBar extends View {
    
    private static final int DEFAULT_HEIGHT_PROGRESS_BAR = 10;
    
    private static final float mRadius = 60;
    
    private int defaultBackgroundColor = Color.parseColor("#DDE4F4");
    
    private int defaultProgressBarColor = Color.parseColor("#3D7EFE");

    
    protected Paint mPaint = new Paint();
    
    protected float mOffset = 0;
    protected float mDefaultOffset = 10;

    
    protected int mProgressBarHeight = dp2px(DEFAULT_HEIGHT_PROGRESS_BAR);

    
    protected float mRealWidth;
    
    private int mMax = 100;
    
    private int mProgress = 0;
    
    private float progressWith = 0;


    public SegmentProgressBar(Context context) {
        this(context, null);
    }

    public SegmentProgressBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SegmentProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initDefaultValues(context, attrs, defStyleAttr);
        init();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public SegmentProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initDefaultValues(context, attrs, defStyleAttr);
        init();
    }

    
    private void initDefaultValues(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        TypedArray arr =
                context.obtainStyledAttributes(attrs, R.styleable.ProgressBar, defStyleAttr, defStyleAttr);
        if (arr != null) {
            mProgress = arr.getInt(R.styleable.ProgressBar_progress, 0);
            mMax = arr.getInt(R.styleable.ProgressBar_max, 0);
            defaultBackgroundColor = arr.getColor(R.styleable.ProgressBar_progressBackground, Color.parseColor("#DDE4F4"));
            defaultProgressBarColor = arr.getColor(R.styleable.ProgressBar_progressBarColor, Color.parseColor("#3D7EFE"));
        }
        arr.recycle();
    }


    
    private void init() {
    }


    
    public void setMax(int max) {
        this.mMax = max;
        if (max > 0) {
            mOffset = mRealWidth / mMax / 8;
            if (mOffset > mDefaultOffset) {
                mOffset = mDefaultOffset;
            }
            progressWith = (mRealWidth - (mMax - 1) * mOffset) / mMax;
        }
        invalidate();
    }

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

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        //高度
        int height = measureHeight(heightMeasureSpec);
        //必须调用该方法来存储View经过测量的到的宽度和高度
        setMeasuredDimension(width, height);
        //真正的宽度值是减去左右padding
        mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();
        //使用画笔在画布上绘制进度
        if (mMax > 0) {
            mOffset = mRealWidth / mMax / 8;
            if (mOffset > mDefaultOffset) {
                mOffset = mDefaultOffset;
            }
            progressWith = (mRealWidth - (mMax - 1) * mOffset) / mMax;
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //真正的宽度值是减去左右padding
        mRealWidth = w - getPaddingRight() - getPaddingLeft();
        //使用画笔在画布上绘制进度
        if (mMax > 0) {
            mOffset = mRealWidth / mMax / 8;
            if (mOffset > mDefaultOffset) {
                mOffset = mDefaultOffset;
            }
            progressWith = (mRealWidth - (mMax - 1) * mOffset) / mMax;
        }
        invalidate();
    }

    
    private int measureHeight(int measureSpec) {
        int result = 0;
        //父布局告诉我们控件的类型
        int specMode = MeasureSpec.getMode(measureSpec);
        //父布局传过来的视图大小
        int specSize = MeasureSpec.getSize(measureSpec);
        if (specMode == MeasureSpec.EXACTLY) {
            result = specSize;
        } else {
            result = (int) (getPaddingTop() + getPaddingBottom() + mProgressBarHeight);
            if (specMode == MeasureSpec.AT_MOST) {
                result = Math.min(result, specSize);
            }
        }
        return result;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(defaultBackgroundColor);
        //设置画笔类型
        mPaint.setStyle(Paint.Style.FILL);
        //去除锯齿
        mPaint.setAntiAlias(true);
        //使用画笔在画布上绘制背景
        canvas.drawRoundRect(0, 0, mRealWidth, getHeight(), mRadius, mRadius, mPaint);
        //绘制进度条
        mPaint.setColor(defaultProgressBarColor);
        for (int i = 0; i < mProgress; i++) {
            canvas.drawRoundRect(i * (progressWith + mOffset), 0, progressWith + i * (progressWith + mOffset), getHeight(), mRadius, mRadius, mPaint);
        }
    }

    
    protected int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, getResources().getDisplayMetrics());
    }
}

别忘了在value下的attr.xml加上默认属性配置


<!--分段式进度条-->
    <declare-styleable name="ProgressBar">
        <attr name="progress" format="integer" />
     <attr name="max" format="integer" />
        <attr name="progressBarColor" format="color" />
        <attr name="progressBackground" format="color" />
</declare-styleable>

在布局中使用


<com.djt.aienglish.widget.SegmentProgressBar
                    android:id="@+id/spb"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    app:max="10"
                    app:progress="1" />

最后再来一个实际使用效果。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯