阶段进度条

本文介绍如何使用前端技术实现一个阶段进度条,用于直观展示项目各阶段的完成情况。通过创建动态更新的数据模型,结合CSS和JavaScript,我们可以构建一个响应式的进度条组件,帮助团队更好地管理和监控项目进度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class PhaseProgressView extends View {

    // 节点连线宽度
    private int mLineWidth;

    // 节点个数
    private int mNodeNum;

    // 选中节点位置
    private int mNodeIndex;

    private Paint mNormalPaint;
    private Paint mSelectedPaint;
    private Path mNormalPath;
    private Path mSelectedPath;

    private Context mContext;
    private int mStartX;

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

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

    public PhaseProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PhaseProgressBar);
        int normalColor = ta.getColor(R.styleable.PhaseProgressBar_phase_normal_color, Color.GRAY);
        int selectedColor = ta.getColor(R.styleable.PhaseProgressBar_phase_selected_color, Color.GREEN);
        mNodeNum = ta.getInteger(R.styleable.PhaseProgressBar_phase_node_num, 2);
        mNodeIndex = ta.getInteger(R.styleable.PhaseProgressBar_phase_current_node_index, 0);

        ta.recycle();

        mNormalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mNormalPaint.setColor(normalColor);
        mNormalPaint.setStyle(Paint.Style.FILL);

        mSelectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mSelectedPaint.setColor(selectedColor);
        mSelectedPaint.setStyle(Paint.Style.FILL);

        mNormalPath = new Path();
        mSelectedPath = new Path();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        mLineWidth = heightSize;
        setMeasuredDimension(widthSize, heightSize);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        mNormalPath.reset();
        mSelectedPath.reset();

        int paddingLeft = getPaddingLeft();
        int paddingRight = getPaddingRight();

        mStartX = paddingLeft + 2;
        int endX = getWidth() - paddingRight - 2;

        int gap = (endX - mStartX) / (mNodeNum);
        int radius = 10;

        // 背景线
        mNormalPath.addRoundRect(mStartX + gap * mNodeIndex - radius, (getHeight() - mLineWidth) / 2, endX, (getHeight() + mLineWidth) / 2, radius, radius, Path.Direction.CCW);
        canvas.drawPath(mNormalPath, mNormalPaint);

        // 选中线
        if (mNodeIndex > 0) {
            mSelectedPath.addRoundRect(mStartX, (getHeight() - mLineWidth) / 2, mStartX + gap * mNodeIndex, (getHeight() + mLineWidth) / 2, radius, radius, Path.Direction.CCW);
        }
        canvas.drawPath(mSelectedPath, mSelectedPaint);
    }

    @Override
    public boolean performClick() {
        super.performClick();
        return true;
    }

    public void setNodeIndex(int index) {
        if (index >= mNodeNum) {
            index = mNodeNum;
        }

        this.mNodeIndex = index;
        invalidate();
    }

    public void setNodeNum(int num) {
        this.mNodeNum = num;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值