CircleProgressBar 圆形进度条,支持多种属性

2023-05-16

效果图:,直接从新项目里面摘出来的,给自己做个记录
所以就不多加说明,

在这里插入图片描述

1、自定义控件:网上摘录修改

public class CircleProgressBar extends View {
    private static final int DEFAULT_MAX = 100;
    private static final float MAX_DEGREE = 360.0f;
    private static final float LINEAR_START_DEGREE = 90.0f;

    private static final int LINE = 0;
    private static final int SOLID = 1;
    private static final int SOLID_LINE = 2;

    private static final int LINEAR = 0;
    private static final int RADIAL = 1;
    private static final int SWEEP = 2;

    private static final int DEFAULT_START_DEGREE = -90;

    private static final int DEFAULT_LINE_COUNT = 45;

    private static final float DEFAULT_LINE_WIDTH = 4.0f;
    private static final float DEFAULT_PROGRESS_TEXT_SIZE = 11.0f;
    private static final float DEFAULT_PROGRESS_STROKE_WIDTH = 1.0f;

    private static final String COLOR_FFF2A670 = "#fff2a670";
    private static final String COLOR_FFD3D3D5 = "#ffe3e3e5";

    private final RectF mProgressRectF = new RectF();
    private final Rect mProgressTextRect = new Rect();

    private final Paint mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Paint mProgressBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private final Paint mProgressTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);

    private float mRadius;
    private float mCenterX;
    private float mCenterY;

    private int mProgress;
    private int mMax = DEFAULT_MAX;

    //Only work well in the Line Style, represents the line count of the rings included
    private int mLineCount;
    //Only work well in the Line Style, Height of the line of the progress bar
    private float mLineWidth;

    //Stroke width of the progress of the progress bar
    private float mProgressStrokeWidth;

    //Text size of the progress of the progress bar
    private float mProgressTextSize;

    //Start color of the progress of the progress bar
    private int mProgressStartColor;
    //End color of the progress of the progress bar
    private int mProgressEndColor;
    //Color of the progress value of the progress bar
    private int mProgressTextColor;
    //Background color of the progress of the progress bar
    private int mProgressBackgroundColor;

    //the rotate degree of the canvas, default is -90.
    private int mStartDegree;

    // whether draw the background only outside the progress area or not
    private boolean mDrawBackgroundOutsideProgress;

    //Format the current progress value to the specified format
    private ProgressFormatter mProgressFormatter = new DefaultProgressFormatter();

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({LINE, SOLID, SOLID_LINE})
    private @interface Style {
    }

    //The style of the progress color
    @Style
    private int mStyle;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({LINEAR, RADIAL, SWEEP})
    private @interface ShaderMode {
    }

    //The Shader of mProgressPaint
    @ShaderMode
    private int mShader;
    //The Stroke Cap of mProgressPaint and mProgressBackgroundPaint
    private Paint.Cap mCap;

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

    public CircleProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        initFromAttributes(context, attrs);
        initPaint();
    }

    /**
     * Basic data initialization
     */
    @SuppressWarnings("ResourceType")
    private void initFromAttributes(Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);

        mLineCount = a.getInt(R.styleable.CircleProgressBar_line_count, DEFAULT_LINE_COUNT);

        mStyle = a.getInt(R.styleable.CircleProgressBar_style, LINE);
        mShader = a.getInt(R.styleable.CircleProgressBar_progress_shader, LINEAR);
        mCap = a.hasValue(R.styleable.CircleProgressBar_progress_stroke_cap) ?
                Paint.Cap.values()[a.getInt(R.styleable.CircleProgressBar_progress_stroke_cap, 0)] : Paint.Cap.BUTT;

        mLineWidth = a.getDimensionPixelSize(R.styleable.CircleProgressBar_line_width, UnitUtils.dip2px(getContext(), DEFAULT_LINE_WIDTH));
        mProgressTextSize = a.getDimensionPixelSize(R.styleable.CircleProgressBar_progress_textSize, UnitUtils.dip2px(getContext(), DEFAULT_PROGRESS_TEXT_SIZE));
        mProgressStrokeWidth = a.getDimensionPixelSize(R.styleable.CircleProgressBar_progress_stroke_width, UnitUtils.dip2px(getContext(), DEFAULT_PROGRESS_STROKE_WIDTH));

        mProgressStartColor = a.getColor(R.styleable.CircleProgressBar_progress_start_color, Color.parseColor(COLOR_FFF2A670));
        mProgressEndColor = a.getColor(R.styleable.CircleProgressBar_progress_end_color, Color.parseColor(COLOR_FFF2A670));
        mProgressTextColor = a.getColor(R.styleable.CircleProgressBar_progress_textColor, Color.parseColor(COLOR_FFF2A670));
        mProgressBackgroundColor = a.getColor(R.styleable.CircleProgressBar_progress_background_color, Color.parseColor(COLOR_FFD3D3D5));

        mStartDegree = a.getInt(R.styleable.CircleProgressBar_progress_start_degree, DEFAULT_START_DEGREE);
        mDrawBackgroundOutsideProgress = a.getBoolean(R.styleable.CircleProgressBar_drawBackgroundOutsideProgress, false);

        a.recycle();
    }

    /**
     * Paint initialization
     */
    private void initPaint() {
        mProgressTextPaint.setTextAlign(Paint.Align.CENTER);
        mProgressTextPaint.setTextSize(mProgressTextSize);

        mProgressPaint.setStyle(mStyle == SOLID ? Paint.Style.FILL : Paint.Style.STROKE);
        mProgressPaint.setStrokeWidth(mProgressStrokeWidth);
        mProgressPaint.setColor(mProgressStartColor);
        mProgressPaint.setStrokeCap(mCap);

        mProgressBackgroundPaint.setStyle(mStyle == SOLID ? Paint.Style.FILL : Paint.Style.STROKE);
        mProgressBackgroundPaint.setStrokeWidth(mProgressStrokeWidth);
        mProgressBackgroundPaint.setColor(mProgressBackgroundColor);
        mProgressBackgroundPaint.setStrokeCap(mCap);
    }

    /**
     * The progress bar color gradient,
     * need to be invoked in the {@link #onSizeChanged(int, int, int, int)}
     */
    private void updateProgressShader() {
        if (mProgressStartColor != mProgressEndColor) {
            Shader shader = null;
            switch (mShader) {
                case LINEAR: {
                    shader = new LinearGradient(mProgressRectF.left, mProgressRectF.top,
                            mProgressRectF.left, mProgressRectF.bottom,
                            mProgressStartColor, mProgressEndColor, Shader.TileMode.CLAMP);
                    Matrix matrix = new Matrix();
                    matrix.setRotate(LINEAR_START_DEGREE, mCenterX, mCenterY);
                    shader.setLocalMatrix(matrix);
                    break;
                }
                case RADIAL: {
                    shader = new RadialGradient(mCenterX, mCenterY, mRadius,
                            mProgressStartColor, mProgressEndColor, Shader.TileMode.CLAMP);
                    break;
                }
                case SWEEP: {
                    //arc = radian * radius
                    float radian = (float) (mProgressStrokeWidth / Math.PI * 2.0f / mRadius);
                    float rotateDegrees = (float) (
                            -(mCap == Paint.Cap.BUTT && mStyle == SOLID_LINE ? 0 : Math.toDegrees(radian)));

                    shader = new SweepGradient(mCenterX, mCenterY, new int[]{mProgressStartColor, mProgressEndColor},
                            new float[]{0.0f, 1.0f});
                    Matrix matrix = new Matrix();
                    matrix.setRotate(rotateDegrees, mCenterX, mCenterY);
                    shader.setLocalMatrix(matrix);
                    break;
                }
                default:
                    break;
            }

            mProgressPaint.setShader(shader);
        } else {
            mProgressPaint.setShader(null);
            mProgressPaint.setColor(mProgressStartColor);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.save();
        canvas.rotate(mStartDegree, mCenterX, mCenterY);
        drawProgress(canvas);
        canvas.restore();

        drawProgressText(canvas);
    }

    private void drawProgressText(Canvas canvas) {
        if (mProgressFormatter == null) {
            return;
        }

        CharSequence progressText = mProgressFormatter.format(mProgress, mMax);

        if (TextUtils.isEmpty(progressText)) {
            return;
        }

        mProgressTextPaint.setTextSize(mProgressTextSize);
        mProgressTextPaint.setColor(mProgressTextColor);

        mProgressTextPaint.getTextBounds(String.valueOf(progressText), 0, progressText.length(), mProgressTextRect);
        canvas.drawText(progressText, 0, progressText.length(), mCenterX, mCenterY + mProgressTextRect.height() / 2, mProgressTextPaint);
    }

    private void drawProgress(Canvas canvas) {
        switch (mStyle) {
            case SOLID:
                drawSolidProgress(canvas);
                break;
            case SOLID_LINE:
                drawSolidLineProgress(canvas);
                break;
            case LINE:
            default:
                drawLineProgress(canvas);
                break;
        }
    }

    /**
     * In the center of the drawing area as a reference point , rotate the canvas
     */
    private void drawLineProgress(Canvas canvas) {
        float unitDegrees = (float) (2.0f * Math.PI / mLineCount);
        float outerCircleRadius = mRadius;
        float interCircleRadius = mRadius - mLineWidth;

        int progressLineCount = (int) ((float) mProgress / (float) mMax * mLineCount);

        for (int i = 0; i < mLineCount; i++) {
            float rotateDegrees = i * -unitDegrees;

            float startX = mCenterX + (float) Math.cos(rotateDegrees) * interCircleRadius;
            float startY = mCenterY - (float) Math.sin(rotateDegrees) * interCircleRadius;

            float stopX = mCenterX + (float) Math.cos(rotateDegrees) * outerCircleRadius;
            float stopY = mCenterY - (float) Math.sin(rotateDegrees) * outerCircleRadius;

            if (mDrawBackgroundOutsideProgress) {
                if (i >= progressLineCount) {
                    canvas.drawLine(startX, startY, stopX, stopY, mProgressBackgroundPaint);
                }
            } else {
                canvas.drawLine(startX, startY, stopX, stopY, mProgressBackgroundPaint);
            }

            if (i < progressLineCount) {
                canvas.drawLine(startX, startY, stopX, stopY, mProgressPaint);
            }
        }
    }

    /**
     * Just draw arc
     */
    private void drawSolidProgress(Canvas canvas) {
        if (mDrawBackgroundOutsideProgress) {
            float startAngle = MAX_DEGREE * mProgress / mMax;
            float sweepAngle = MAX_DEGREE - startAngle;
            canvas.drawArc(mProgressRectF, startAngle, sweepAngle, true, mProgressBackgroundPaint);
        } else {
            canvas.drawArc(mProgressRectF, 0.0f, MAX_DEGREE, true, mProgressBackgroundPaint);
        }
        canvas.drawArc(mProgressRectF, 0.0f, MAX_DEGREE * mProgress / mMax, true, mProgressPaint);
    }

    /**
     * Just draw arc
     */
    private void drawSolidLineProgress(Canvas canvas) {
        if (mDrawBackgroundOutsideProgress) {
            float startAngle = MAX_DEGREE * mProgress / mMax;
            float sweepAngle = MAX_DEGREE - startAngle;
            canvas.drawArc(mProgressRectF, startAngle, sweepAngle, false, mProgressBackgroundPaint);
        } else {
            canvas.drawArc(mProgressRectF, 0.0f, MAX_DEGREE, false, mProgressBackgroundPaint);
        }
        canvas.drawArc(mProgressRectF, 0.0f, MAX_DEGREE * mProgress / mMax, false, mProgressPaint);
    }

    /**
     * When the size of CircleProgressBar changed, need to re-adjust the drawing area
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterX = w / 2;
        mCenterY = h / 2;

        mRadius = Math.min(mCenterX, mCenterY);
        mProgressRectF.top = mCenterY - mRadius;
        mProgressRectF.bottom = mCenterY + mRadius;
        mProgressRectF.left = mCenterX - mRadius;
        mProgressRectF.right = mCenterX + mRadius;

        updateProgressShader();

        //Prevent the progress from clipping
        mProgressRectF.inset(mProgressStrokeWidth / 2, mProgressStrokeWidth / 2);
    }

    public void setProgressFormatter(ProgressFormatter progressFormatter) {
        this.mProgressFormatter = progressFormatter;
        invalidate();
    }

    public void setProgressStrokeWidth(float progressStrokeWidth) {
        this.mProgressStrokeWidth = progressStrokeWidth;
        mProgressRectF.inset(mProgressStrokeWidth / 2, mProgressStrokeWidth / 2);
        invalidate();
    }

    public void setProgressTextSize(float progressTextSize) {
        this.mProgressTextSize = progressTextSize;
        invalidate();
    }

    public void setProgressStartColor(int progressStartColor) {
        this.mProgressStartColor = progressStartColor;
        updateProgressShader();
        invalidate();
    }

    public void setProgressEndColor(int progressEndColor) {
        this.mProgressEndColor = progressEndColor;
        updateProgressShader();
        invalidate();
    }

    public void setProgressTextColor(int progressTextColor) {
        this.mProgressTextColor = progressTextColor;
        invalidate();
    }

    public void setProgressBackgroundColor(int progressBackgroundColor) {
        this.mProgressBackgroundColor = progressBackgroundColor;
        mProgressBackgroundPaint.setColor(mProgressBackgroundColor);
        invalidate();
    }

    public void setLineCount(int lineCount) {
        this.mLineCount = lineCount;
        invalidate();
    }

    public void setLineWidth(float lineWidth) {
        this.mLineWidth = lineWidth;
        invalidate();
    }

    public void setStyle(@Style int style) {
        this.mStyle = style;
        mProgressPaint.setStyle(mStyle == SOLID ? Paint.Style.FILL : Paint.Style.STROKE);
        mProgressBackgroundPaint.setStyle(mStyle == SOLID ? Paint.Style.FILL : Paint.Style.STROKE);
        invalidate();
    }

    public void setShader(@ShaderMode int shader) {
        mShader = shader;
        updateProgressShader();
        invalidate();
    }

    public void setCap(Paint.Cap cap) {
        mCap = cap;
        mProgressPaint.setStrokeCap(cap);
        mProgressBackgroundPaint.setStrokeCap(cap);
        invalidate();
    }

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

    public void setMax(int max) {
        this.mMax = max;
        invalidate();
    }

    public int getProgress() {
        return mProgress;
    }

    public int getMax() {
        return mMax;
    }

    public int getStartDegree() {
        return mStartDegree;
    }

    public void setStartDegree(int startDegree) {
        this.mStartDegree = startDegree;
        invalidate();
    }

    public boolean isDrawBackgroundOutsideProgress() {
        return mDrawBackgroundOutsideProgress;
    }

    public void setDrawBackgroundOutsideProgress(boolean drawBackgroundOutsideProgress) {
        this.mDrawBackgroundOutsideProgress = drawBackgroundOutsideProgress;
        invalidate();
    }

    public interface ProgressFormatter {
        CharSequence format(int progress, int max);
    }

    private static final class DefaultProgressFormatter implements ProgressFormatter {
        private static final String DEFAULT_PATTERN = "%d%%";

        @Override
        public CharSequence format(int progress, int max) {
            return String.format(DEFAULT_PATTERN, (int) ((float) progress / (float) max * 100));
        }
    }

    private static final class SavedState extends BaseSavedState {
        int progress;

        SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            progress = in.readInt();
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeInt(progress);
        }

        public static final Creator<SavedState> CREATOR
                = new Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }

    @Override
    public Parcelable onSaveInstanceState() {
        // Force our ancestor class to save its state
        Parcelable superState = super.onSaveInstanceState();
        SavedState ss = new SavedState(superState);

        ss.progress = mProgress;

        return ss;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());

        setProgress(ss.progress);
    }

}

2、添加上属性

<declare-styleable name="CircleProgressBar">
    <attr name="line_count" format="integer|reference"/>
    <attr name="line_width" format="dimension|reference"/>
    <attr name="progress_start_color" format="color|reference"/>
    <attr name="progress_end_color" format="color|reference"/>
    <attr name="progress_textColor" format="color|reference"/>
    <attr name="progress_textSize" format="dimension|reference"/>
    <attr name="progress_stroke_width" format="dimension|reference"/>
    <attr name="progress_background_color" format="color|reference"/>
    <attr name="progress_start_degree" format="integer|reference"/>
    <attr name="drawBackgroundOutsideProgress" format="boolean|reference"/>
    <attr name="style">
        <enum name="line" value="0"/>
        <enum name="solid" value="1"/>
        <enum name="solid_line" value="2"/>
    </attr>
    <attr name="progress_shader">
        <enum name="linear" value="0"/>
        <enum name="radial" value="1"/>
        <enum name="sweep" value="2"/>
    </attr>
    <attr name="progress_stroke_cap">
        <enum name="butt" value="0"/>
        <enum name="round" value="1"/>
        <enum name="square" value="2"/>
    </attr>
</declare-styleable>

布局:其余布局…………看自己情况了

 <com.youmu.game.mvp.ui.view.circleprogressbar.CircleProgressBar
                    android:id="@+id/progress_experience"
                    app:style="solid_line"
                    android:layout_weight="1"
                    android:layout_marginTop="@dimen/base10dp"
                    app:progress_background_color="#F0F0F0"
                    app:progress_start_color="#FF8F8F"
                    app:progress_end_color="#FF0000"
                    app:progress_stroke_width="@dimen/base10dp"
                    app:progress_textSize="@dimen/text12sp"
                    app:progress_textColor="@color/color_FFFFFF"
                    app:layout_constraintHorizontal_chainStyle="spread"
                    android:layout_width="wrap_content"
                    android:layout_height="@dimen/base90dp" />

    <com.youmu.game.mvp.ui.view.circleprogressbar.CircleProgressBar
                    android:id="@+id/progress_credit"
                    app:style="solid_line"
                    android:layout_marginTop="@dimen/base10dp"
                    app:progress_background_color="#F0F0F0"
                    app:progress_start_color="#8FDFFF"
                    app:progress_end_color="#0A90EC"
                    app:progress_stroke_width="@dimen/base10dp"
                    app:progress_textSize="@dimen/text12sp"
                    app:progress_textColor="@color/color_FFFFFF"
                    app:layout_constraintHorizontal_chainStyle="spread"
                    android:layout_width="wrap_content"
                    android:layout_height="@dimen/base90dp" />

使用:经验值为例
@BindView(R.id.progress_experience)
CircleProgressBar progress_experience;

ValueAnimator animatorexperience = ValueAnimator.ofInt(0, 20);
        animatorexperience.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int progress = (int) animation.getAnimatedValue();
                progress_experience.setProgress(progress);
                if (100 == progress) {
                }
            }
        });
//        animator.setRepeatCount(ValueAnimator.INFINITE);
        animatorexperience.setDuration(5000);
        animatorexperience.start();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CircleProgressBar 圆形进度条,支持多种属性 的相关文章

随机推荐

  • [Index]博文索引

    为了方便查看需要的博文 xff0c 在此给出所有博文的索引链接地址 UAV Software Version xff1a ArduCopter xff08 Ver 3 3 xff09 Hardware Version xff1a pixha
  • NVIDIA JETSON XAVIER NX (四)安装Pytorch和torchvision

    可选择在NX上创建新python环境进行安装 xff0c 避免和其他工程环境发生冲突 xff0c 具体虚拟环境操作步骤可见Python创建虚拟环境 下面就开始安装pytorch的愉快之旅吧 xff01 1 安装相关依赖环境 span cla
  • 使用nuttx写自启任务

    首先从px4学习怎么进行系统任务 px4是通过nsh main里面调用nsh consolemain然后调用rcS文件 xff0c 运用rcS脚本命令启动相应模块 然而经过了一个礼拜的实践 xff08 浪费时间 xff09 xff0c 我发
  • QT常用库、类、函数等

    文章目录 常用基类QObject类内存管理机制 xff1a 父子对象的内存管理机制 QApplication类 xff1a 应用程序类 xff08 一般不直接操纵 xff09 QWidget类 xff1a 窗体类容器控件QStackedWi
  • 单片机中堆栈那些事儿

    堆栈是内存中一段连续的存储区域 xff0c 用来保存一些临时的数据 xff0c 比如 xff0c 可以保存中断指令INT中的标志寄存器值 代码段寄存器CS值 指令指针寄存器IP值 xff1b 还可以用以RET指令从中可以得到返回的地址 xf
  • udp 通信

    1 char strtok char str const char delim 功能 xff1a 对字符串进行切割 参数 xff1a str 要切割的字符串的首地址 delim 切割的规则 返回值 xff1a 切割后字符串的首地址 2 ud
  • Unix网络编程 Ubuntu20.04.2 Visual Studio Code

    Visual Studio Code 说明 1 本文中 表示下一步 下一级菜单和修改为 xff0c 需根据上下文理解 一 环境配置 1 安装gcc g 43 43 和gdb span class token function sudo sp
  • 基于Jetson NX的模型部署

    系统安装 系统安装过程分为3步 xff1a 下载必要的软件及镜像 Jetson Nano Developer Kit SD卡映像 https developer nvidia com jetson nano sd card image Wi
  • C51单片机学习笔记——秒表

    前言 不知不觉我又被自己的惰性拖住了小一个月 xff0c 今天在宿舍窗边吸烟时候 xff0c 看着楼下人来人往的道路不由自主的感到一丝惭愧 xff0c 手里的小视频也被我刷出来一条鸡汤 xff0c 在这儿我要写下来记录给将来又在颓废的我 x
  • arduino学习——UART串口通信

    Serial begin 初始化串口 用作串口的启动 xff0c 常放置在setup xff08 xff09 中 原型 xff1a Serial begin speed Serial begin speed config 参数 xff1a
  • arduino学习——servo类 控制舵机

    硬件 WeMos D1平台 43 SG90舵机 SG90舵机相关介绍 xff1a 角度 xff1a 90度 180度通用 红色为5V电源线 xff0c 棕色为地线 xff0c 橙色为信号线 无负载转速 xff1a 0 12秒 60度 xff
  • DSP28335笔记 ———— 中断系统 之 外部中断

    DSP28335笔记 中断系统 之 外部中断 我用的开发板是 硬汉DSP28335开发板 xff0c 文中对于硬件的描述可以说是没有 xff0c 而且我还没有附上电路图希望在看的朋友不要喷我 然后 xff0c 我个人感觉普中的DSP2833
  • DSP28335笔记 —— 定时器

    DSP28335笔记 定时器 相比于STM32 xff0c DSP28335的定时器好像真的简单了好多 xff0c 从定时器个数来讲只有3个 xff0c 时钟源只能是系统时钟 xff0c 而且计数方向也只有向下计数 单纯且善良的定时器 xf
  • C语言线程基本函数

    学习笔记 xff1a C语言线程基本函数 学习内容 xff1a 线程常用基本函数 xff1a pthread create 创建线程pthread exit 退出当前线程pthread join 等待其他线程结束pthread self 自
  • 《大话设计模式》笔记——简单工厂模式

    前言 我 xff08 长胖的阿诏 xff09 是新入行的嵌入式程序员 xff0c 所以用C语言做示例演示 xff0c 我看到书上都是 C 语言的代码 xff0c 所以我只能先领会精神 xff0c 再通过C语言复刻 在我的资源里好像没有见过用
  • 《大话设计模式》笔记——策略模式

    策略模式 34 我 34 的理解 策略模式 是指同一个对象在不同情况下的策略行为有所差异 xff0c 继续以之前的四则运算为例 加 减 乘 除 就是两个参数在不同情况下计算过程的差异性行为 所以在某种程度上 xff0c 策略模式可能比简单工
  • md文件目录生成器

    md文件目录生成器 目录 md文件目录生成器 md文件目录生成器 step1 下载脚本文件 step1 下载脚本文件 step2 生成脚本文件 step2 生成脚本文件 step3 设置环境变量 step3 设置环境变量 step4 可以用
  • Python __file__ 详解

    这个功能纠结了一下午 xff0c 做了测试以后总算是明白了 file 表示显示文件当前的位置 但是 xff1a 如果当前文件包含在sys path里面 xff0c 那么 xff0c file 返回一个相对路径 xff01 如果当前文件不包含
  • 48.HTTP基本认证与摘要认证

    文章目录 基本认证摘要认证 转载请注明原始出处 xff1a http blog csdn net a464057216 article details 52705855 后续此博客不再更新 xff0c 欢迎大家搜索关注微信公众号 测开之美
  • CircleProgressBar 圆形进度条,支持多种属性

    效果图 xff1a xff0c 直接从新项目里面摘出来的 xff0c 给自己做个记录 所以就不多加说明 xff0c 1 自定义控件 xff1a 网上摘录修改 public class CircleProgressBar extends Vi