zoukankan      html  css  js  c++  java
  • android ProgressBar自定义半圆形进度条

    不多说,直接上代码,可直接看注释,类似于一个仪盘表,下面的类可当做是一个工具类,有什么要修改的地方,可直接在此类中添加

    public class ColorArcProgressBar extends View{

    private int mWidth;
    private int mHeight;
    private int diameter = 500; //直径
    private float centerX; //圆心X坐标
    private float centerY; //圆心Y坐标

    private Paint allArcPaint;
    private Paint progressPaint;
    private Paint vTextPaint;
    private Paint hintPaint;
    private Paint degreePaint;
    private Paint curSpeedPaint;

    private RectF bgRect;

    private ValueAnimator progressAnimator;
    private PaintFlagsDrawFilter mDrawFilter;
    private SweepGradient sweepGradient;
    private Matrix rotateMatrix;

    private float startAngle = 135;
    private float sweepAngle = 270;
    private float currentAngle = 0;
    private float lastAngle;
    private int[] colors = new int[]{Color.GREEN, Color.YELLOW, Color.RED, Color.RED};
    private float maxValues = 60;
    private float curValues = 0;
    private float bgArcWidth = dipToPx(2);
    private float progressWidth = dipToPx(10);
    private float textSize = dipToPx(60);
    private float hintSize = dipToPx(15);
    private float curSpeedSize = dipToPx(25);
    private int aniSpeed = 1000;
    private float longdegree = dipToPx(13);
    private float shortdegree = dipToPx(5);
    private final int DEGREE_PROGRESS_DISTANCE = dipToPx(8);

    private String hintColor = "#575757";
    private String contentColor = "#3CCDB1";
    private String longDegreeColor = "#111111";
    private String shortDegreeColor = "#111111";
    private String bgArcColor = "#D6F7EB"; //圆圈背景色(画笔颜色)
    private String titleString;
    private String hintString;

    private boolean isShowCurrentSpeed = true;
    private boolean isNeedTitle;
    private boolean isNeedUnit;
    private boolean isNeedDial;
    private boolean isNeedContent;

    // sweepAngle / maxValues 的值
    private float k;

    public ColorArcProgressBar(Context context) {
    super(context, null);
    initView();
    }

    public ColorArcProgressBar(Context context, AttributeSet attrs) {
    super(context, attrs, 0);
    initCofig(context, attrs);
    initView();
    }

    public ColorArcProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initCofig(context, attrs);
    initView();
    }

    /**
    * 初始化布局配置
    * @param context
    * @param attrs
    */
    private void initCofig(Context context, AttributeSet attrs) {
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ColorArcProgressBar);
    int color1 = a.getColor(R.styleable.ColorArcProgressBar_front_color1, Color.GREEN);
    int color2 = a.getColor(R.styleable.ColorArcProgressBar_front_color2, color1);
    int color3 = a.getColor(R.styleable.ColorArcProgressBar_front_color3, color1);
    colors = new int[]{color1, color2, color3, color3};

    sweepAngle = a.getInteger(R.styleable.ColorArcProgressBar_total_engle, 270);
    bgArcWidth = a.getDimension(R.styleable.ColorArcProgressBar_back_width, dipToPx(2));
    progressWidth = a.getDimension(R.styleable.ColorArcProgressBar_front_width, dipToPx(10));
    isNeedTitle = a.getBoolean(R.styleable.ColorArcProgressBar_is_need_title, false);
    isNeedContent = a.getBoolean(R.styleable.ColorArcProgressBar_is_need_content, false);
    isNeedUnit = a.getBoolean(R.styleable.ColorArcProgressBar_is_need_unit, false);
    isNeedDial = a.getBoolean(R.styleable.ColorArcProgressBar_is_need_dial, false);
    hintString = a.getString(R.styleable.ColorArcProgressBar_string_unit);
    titleString = a.getString(R.styleable.ColorArcProgressBar_string_title);
    curValues = a.getFloat(R.styleable.ColorArcProgressBar_current_value, 0);
    maxValues = a.getFloat(R.styleable.ColorArcProgressBar_max_value, 60);
    setCurrentValues(curValues);
    setMaxValues(maxValues);
    a.recycle();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = (int) (2 * longdegree + progressWidth + diameter + 2 * DEGREE_PROGRESS_DISTANCE);
    int height= (int) (2 * longdegree + progressWidth + diameter + 2 * DEGREE_PROGRESS_DISTANCE);
    setMeasuredDimension(width, height);
    }

    private void initView() {

    diameter = 3 * getScreenWidth() / 5;
    //弧形的矩阵区域
    bgRect = new RectF();
    bgRect.top = longdegree + progressWidth/2 + DEGREE_PROGRESS_DISTANCE;
    bgRect.left = longdegree + progressWidth/2 + DEGREE_PROGRESS_DISTANCE;
    bgRect.right = diameter + (longdegree + progressWidth/2 + DEGREE_PROGRESS_DISTANCE);
    bgRect.bottom = diameter + (longdegree + progressWidth/2 + DEGREE_PROGRESS_DISTANCE);

    //圆心
    centerX = (2 * longdegree + progressWidth + diameter + 2 * DEGREE_PROGRESS_DISTANCE)/2;
    centerY = (2 * longdegree + progressWidth + diameter + 2 * DEGREE_PROGRESS_DISTANCE)/2;

    //外部刻度线
    degreePaint = new Paint();
    degreePaint.setColor(Color.parseColor(longDegreeColor));

    //整个弧形
    allArcPaint = new Paint();
    allArcPaint.setAntiAlias(true);
    allArcPaint.setStyle(Paint.Style.STROKE);
    allArcPaint.setStrokeWidth(bgArcWidth);
    allArcPaint.setColor(Color.parseColor(bgArcColor));
    allArcPaint.setStrokeCap(Paint.Cap.ROUND);

    //当前进度的弧形
    progressPaint = new Paint();
    progressPaint.setAntiAlias(true);
    progressPaint.setStyle(Paint.Style.STROKE);
    progressPaint.setStrokeCap(Paint.Cap.ROUND);
    progressPaint.setStrokeWidth(progressWidth);
    progressPaint.setColor(Color.GREEN);

    //内容显示文字
    vTextPaint = new Paint();
    vTextPaint.setTextSize(textSize);
    vTextPaint.setColor(Color.parseColor(contentColor));
    vTextPaint.setTextAlign(Paint.Align.CENTER);

    //显示单位文字
    hintPaint = new Paint();
    hintPaint.setTextSize(hintSize);
    hintPaint.setColor(Color.parseColor(hintColor));
    hintPaint.setTextAlign(Paint.Align.CENTER);

    //显示标题文字
    curSpeedPaint = new Paint();
    curSpeedPaint.setTextSize(curSpeedSize);
    curSpeedPaint.setColor(Color.parseColor(hintColor));
    curSpeedPaint.setTextAlign(Paint.Align.CENTER);

    mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
    sweepGradient = new SweepGradient(centerX, centerY, colors, null);
    rotateMatrix = new Matrix();

    }

    @Override
    protected void onDraw(Canvas canvas) {
    //抗锯齿
    canvas.setDrawFilter(mDrawFilter);

    if (isNeedDial) {
    //画刻度线
    for (int i = 0; i < 40; i++) {
    if (i > 15 && i < 25) {
    canvas.rotate(9, centerX, centerY);
    continue;
    }
    if (i % 5 == 0) {
    degreePaint.setStrokeWidth(dipToPx(2));
    degreePaint.setColor(Color.parseColor(longDegreeColor));
    canvas.drawLine(centerX, centerY - diameter / 2 - progressWidth / 2 - DEGREE_PROGRESS_DISTANCE,
    centerX, centerY - diameter / 2 - progressWidth / 2 - DEGREE_PROGRESS_DISTANCE - longdegree, degreePaint);
    } else {
    degreePaint.setStrokeWidth(dipToPx(1.4f));
    degreePaint.setColor(Color.parseColor(shortDegreeColor));
    canvas.drawLine(centerX, centerY - diameter / 2 - progressWidth / 2 - DEGREE_PROGRESS_DISTANCE - (longdegree - shortdegree) / 2,
    centerX, centerY - diameter / 2 - progressWidth / 2 - DEGREE_PROGRESS_DISTANCE - (longdegree - shortdegree) / 2 - shortdegree, degreePaint);
    }

    canvas.rotate(9, centerX, centerY);
    }
    }

    //整个弧
    canvas.drawArc(bgRect, startAngle, sweepAngle, false, allArcPaint);

    //设置渐变色
    rotateMatrix.setRotate(130, centerX, centerY);
    sweepGradient.setLocalMatrix(rotateMatrix);
    progressPaint.setShader(sweepGradient);

    //当前进度
    canvas.drawArc(bgRect, startAngle, currentAngle, false, progressPaint);

    if (isNeedContent) {
    canvas.drawText(String.format("%.0f", curValues), centerX, centerY + textSize / 3, vTextPaint);
    }
    if (isNeedUnit) {
    canvas.drawText(hintString, centerX, centerY + 2 * textSize / 3, hintPaint);
    }
    if (isNeedTitle) {
    canvas.drawText(titleString, centerX, centerY - 2 * textSize / 3, curSpeedPaint);
    }

    invalidate();

    }

    /**
    * 设置最大值
    * @param maxValues
    */
    public void setMaxValues(float maxValues) {
    this.maxValues = maxValues;
    k = sweepAngle/maxValues;
    }

    /**
    * 设置当前值
    * @param currentValues
    */
    public void setCurrentValues(float currentValues) {
    if (currentValues > maxValues) {
    currentValues = maxValues;
    }
    if (currentValues < 0) {
    currentValues = 0;
    }
    this.curValues = currentValues;
    lastAngle = currentAngle;
    setAnimation(lastAngle, currentValues * k, aniSpeed);
    }

    /**
    * 设置整个圆弧宽度
    * @param bgArcWidth
    */
    public void setBgArcWidth(int bgArcWidth) {
    this.bgArcWidth = bgArcWidth;
    }

    /**
    * 设置进度宽度
    * @param progressWidth
    */
    public void setProgressWidth(int progressWidth) {
    this.progressWidth = progressWidth;
    }

    /**
    * 设置速度文字大小
    * @param textSize
    */
    public void setTextSize(int textSize) {
    this.textSize = textSize;
    }

    /**
    * 设置单位文字大小
    * @param hintSize
    */
    public void setHintSize(int hintSize) {
    this.hintSize = hintSize;
    }

    /**
    * 设置单位文字
    * @param hintString
    */
    public void setUnit(String hintString) {
    this.hintString = hintString;
    invalidate();
    }

    /**
    * 设置直径大小
    * @param diameter
    */
    public void setDiameter(int diameter) {
    this.diameter = dipToPx(diameter);
    }

    /**
    * 设置标题
    * @param title
    */
    private void setTitle(String title){
    this.titleString = title;
    }

    /**
    * 设置是否显示标题
    * @param isNeedTitle
    */
    private void setIsNeedTitle(boolean isNeedTitle) {
    this.isNeedTitle = isNeedTitle;
    }

    /**
    * 设置是否显示单位文字
    * @param isNeedUnit
    */
    private void setIsNeedUnit(boolean isNeedUnit) {
    this.isNeedUnit = isNeedUnit;
    }

    /**
    * 设置是否显示外部刻度盘
    * @param isNeedDial
    */
    private void setIsNeedDial(boolean isNeedDial) {
    this.isNeedDial = isNeedDial;
    }

    /**
    * 为进度设置动画
    * @param last
    * @param current
    */
    private void setAnimation(float last, float current, int length) {
    progressAnimator = ValueAnimator.ofFloat(last, current);
    progressAnimator.setDuration(length);
    progressAnimator.setTarget(currentAngle);
    progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    currentAngle= (Float) animation.getAnimatedValue();
    curValues = currentAngle/k;
    }
    });
    progressAnimator.start();
    }

    /**
    * dip 转换成px
    * @param dip
    * @return
    */
    private int dipToPx(float dip) {
    float density = getContext().getResources().getDisplayMetrics().density;
    return (int)(dip * density + 0.5f * (dip >= 0 ? 1 : -1));
    }

    /**
    * 得到屏幕宽度
    * @return
    */
    private int getScreenWidth() {
    WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics displayMetrics = new DisplayMetrics();
    windowManager.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics.widthPixels;
    }
    }

    以下为xml中布局

    <com.android.cft.jinju.utils.ColorArcProgressBar
    android:id="@+id/health_bar"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:layout_centerInParent="true"
    app:back_color="@android:color/darker_gray"
    app:back_width="10dp"
    app:front_color1="#4BD866"
    app:front_color2="#46D480"
    app:front_color3="@color/title_green"
    app:front_width="13dp"
    app:is_need_content="true"
    app:is_need_unit="true"
    app:max_value="100"
    app:string_unit=""
    app:is_need_title="true"
    app:string_title="今日步数"
    app:total_engle="270" />

    以下为在activity或fragment中调用此自定义半圆

    定义:private ColorArcProgressBar arcProgressBar;

    赋值:arcProgressBar = (ColorArcProgressBar) view.findViewById(R.id.health_bar);

    设置最大值:arcProgressBar.setMaxValues(100);

    设值:arcProgressBar.setMaxValues(1000);

  • 相关阅读:
    设计一个字符串类,并将字符串处理函数的内容进行封装
    C++字符串处理函数【自写】
    文件共享服务器nfs搭建过程
    svn服务器的搭建过程 主要为服务端
    uwsgi和wsgi
    熟悉了下HTTP协议
    ModelForm views.py
    隐藏tomcat nginx版本信息
    csrf
    开发模式
  • 原文地址:https://www.cnblogs.com/xxzjyf/p/5896916.html
Copyright © 2011-2022 走看看