• Android自定义圆角矩形进度条2


    效果图:

      或 

    方法讲解:

    (1)invalidate()方法

    invalidate()是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时, 调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。一般在自定义控件中会用到这个方法。

    (2)RectF方法的应用

    RectF是用来绘画矩形的方法。 

    RectF(left,top,right,bottom),四个参数的含义分别是父控件距离矩形左上右下边距的距离,以下用图来说明:

    drawRoundRect方法是用来绘制圆角矩形的,它的参数如下: 
    参数说明 

    rect:RectF对象。 
    rx:x方向上的圆角半径。 
    ry:y方向上的圆角半径。 
    paint:绘制时所使用的画笔。

    (3)onMeasure方法

    指定自定义控件在屏幕上的大小,onMeasure方法的两个参数是由上一层控件 传入的大小,而且是模式和尺寸混合在一起的数值,需要MeasureSpec.getMode(widthMeasureSpec) 得到模式,MeasureSpec.getSize(widthMeasureSpec)得到尺寸。

    onMeasure的几种模式分别为EXACTLY,AT_MOST,UNSPECIFIED。

    [1]MeasureSpec.EXACTLY

    MeasureSpec.EXACTLY是精确尺寸,当我们将控件的layout_width或layout_height指定为具体数值时如andorid:layout_width=”50dip”,或者为FILL_PARENT是,都是控件大小已经确定的情况,都是精确尺寸。

    [2]MeasureSpec.AT_MOST

    MeasureSpec.AT_MOST是最大尺寸,当控件的layout_width或layout_height指定为WRAP_CONTENT时,控件大小一般随着控件的子空间或内容进行变化,此时控件尺寸只要不超过父控件允许的最大尺寸即可。因此,此时的mode是AT_MOST,size给出了父控件允许的最大尺寸。

    [3]MeasureSpec.UNSPECIFIED

    MeasureSpec.UNSPECIFIED是未指定尺寸,这种情况不多,一般都是父控件是AdapterView,通过measure方法传入的模式。

    实现步骤:

    a、在values文件夹下新建attrs.xml,内容如下:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
    <declare-styleable name="CircleProgressBar">
    <attr name="croundColor" format="color"/>
    <attr name="croundProgressColor" format="color"/>
    <attr name="cfillColor" format="color"/>
    <attr name="croundWidth" format="dimension"></attr>
    <attr name="croundProgressWidth" format="dimension"></attr> 
    <attr name="ctextColor" format="color" /> 
    <attr name="ctextSize" format="dimension" /> 
    <attr name="cnumberSize" format="dimension" /> 
    <attr name="cparaLable" format="string" />
    <attr name="cunitLable" format="string" /> 
    </declare-styleable>
    
    <declare-styleable name="RoundRectProgressBar">
    <attr name="cbarRoundColor" format="color"/>
    <attr name="cbarProgressColor" format="color"/>
    <attr name="cbarFillColor" format="color"/>
    <attr name="cbarOrientation">
      <enum name="HORIZONTAL" value="0"></enum>
      <enum name="VERTICAL" value="1"></enum>
    </attr>
    </declare-styleable>
    
    </resources>
    

      


    b、新建RoundRectProgressBar类继承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.RectF;
    import android.util.AttributeSet;
    import android.view.View;
    
    /**
    * 自定义圆角矩形进度条view
    *
    * @author xl
    */
    public class RoundRectProgressBar extends View {
    
    private final static String TAG = RoundRectProgressBar.class.getSimpleName();
    
    /**
    * 画笔对象的引用
    */
    private Paint paint;
    
    /**
    * 圆角环的颜色
    */
    private int roundColor;
    
    /**
    * 进度的颜色
    */
    private int fillProgressColor;
    
    /**
    * 填充的颜色
    */
    private int fillColor;
    
    /**
    * 圆角矩形宽度
    */
    private int roundWidth;
    
    /**
    * 圆角矩形高度
    */
    private int roundHeight;
    
    /**
    * 进度条方向,0水平,1垂直
    */
    private int barOrientation;
    
    /**
    * 进度条最大值
    */
    private float max = 100;
    
    /**
    * 进度条当前值
    */
    private float progress = 30;
    
    public RoundRectProgressBar(Context context) {
    this(context, null);
    }
    
    public RoundRectProgressBar(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
    }
    
    public RoundRectProgressBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    //获取画笔
    paint = new Paint();
    TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundRectProgressBar);
    //获取自定义属性和默认值
    roundColor = mTypedArray.getColor(R.styleable.RoundRectProgressBar_cbarRoundColor, Color.RED);
    fillProgressColor = mTypedArray.getColor(R.styleable.RoundRectProgressBar_cbarProgressColor, Color.GREEN);
    fillColor = mTypedArray.getColor(R.styleable.RoundRectProgressBar_cbarFillColor, Color.BLUE);
    barOrientation = mTypedArray.getInt(R.styleable.RoundRectProgressBar_cbarOrientation, 0);
    //回收TypedArray资源
    mTypedArray.recycle();
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //设置抗锯齿效果
    paint.setAntiAlias(true);
    //设置画笔颜色
    paint.setColor(roundColor);
    //进度方向
    if (barOrientation == 0) {
    //水平,向右
    try {
    int round = roundHeight / 2;
    //RectF:绘制矩形,四个参数分别是left,top,right,bottom,类型是单精度浮点数
    RectF rf = new RectF(0, 0, roundWidth, roundHeight);
    //绘制圆角矩形,背景色为画笔颜色
    canvas.drawRoundRect(rf, round, round, paint);
    //设置progress内部是灰色
    paint.setColor(fillColor);
    RectF rectBlackBg = new RectF(2, 2, roundWidth - 2, roundHeight - 2);
    canvas.drawRoundRect(rectBlackBg, round, round, paint);
    //设置进度条进度及颜色
    float section = progress / max;
    RectF rectProgressBg = new RectF(2, 2, (roundWidth - 2) * section, roundHeight - 2);
    if (section != 0.0f) {
    paint.setColor(fillProgressColor);
    } else {
    paint.setColor(Color.TRANSPARENT);
    }
    canvas.drawRoundRect(rectProgressBg, round, round, paint);
    } catch (Exception e) {
    e.printStackTrace();
    }
    } else {
    //垂直,向上
    try {
    int round = roundWidth / 2;
    //RectF:绘制矩形,四个参数分别是left,top,right,bottom,类型是单精度浮点数
    RectF rf = new RectF(0, 0, roundWidth, roundHeight);
    //绘制圆角矩形,背景色为画笔颜色
    canvas.drawRoundRect(rf, round, round, paint);
    //设置progress内部是灰色
    paint.setColor(fillColor);
    RectF rectBlackBg = new RectF(2, 2, roundWidth - 2, roundHeight - 2);
    canvas.drawRoundRect(rectBlackBg, round, round, paint);
    //设置进度条进度及颜色
    float section = progress / max;
    RectF rectProgressBg = new RectF(2, roundHeight - 2 - (roundHeight - 4) * section, roundWidth - 2, roundHeight - 2);
    if (section != 0.0f) {
    paint.setColor(fillProgressColor);
    } else {
    paint.setColor(Color.TRANSPARENT);
    }
    canvas.drawRoundRect(rectProgressBg, round, round, paint);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
    
    /**
    * dip转px
    *
    * @param dip
    * @return
    */
    private int dipToPx(int dip) {
    float scale = getContext().getResources().getDisplayMetrics().density;
    //加0.5是为了四舍五入
    return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
    }
    
    /**
    * 指定自定义控件在屏幕上的大小,onMeasure方法的两个参数是由上一层控件
    * 传入的大小,而且是模式和尺寸混合在一起的数值,需要MeasureSpec.getMode(widthMeasureSpec)
    * 得到模式,MeasureSpec.getSize(widthMeasureSpec)得到尺寸
    */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
    int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
    //MeasureSpec.EXACTLY,精确尺寸
    if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
    roundWidth = widthSpecSize;
    } else {
    roundWidth = 0;
    }
    if (heightSpecMode == MeasureSpec.EXACTLY || heightSpecMode == MeasureSpec.AT_MOST) {
    roundHeight = heightSpecSize;
    } else {
    roundHeight = 0;
    }
    //MeasureSpec.AT_MOST,最大尺寸,只要不超过父控件允许的最大尺寸即可,MeasureSpec.UNSPECIFIED未指定尺寸
    //if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
    // roundHeight = dipToPx(20);
    //} else {
    // roundHeight = heightSpecSize;
    //}
    //设置控件实际大小
    setMeasuredDimension(roundWidth, roundHeight);
    }
    
    
    /**
    * 设置进度
    *
    * @param progress
    */
    public synchronized void setProgress(float progress) {
    if (progress < 0) {
    throw new IllegalArgumentException("value can not be negative");
    }
    if (progress > max) {
    this.progress = max;
    } else {
    this.progress = progress;
    }
    postInvalidate();
    }
    
    /**
    * 设置最大值
    *
    * @param max
    */
    public synchronized void setMax(float max) {
    if (max < 0) {
    throw new IllegalArgumentException("value can not be negative");
    }
    this.max = max;
    }
    
    }
    

      


    c、布局文件中引用activity_main.xml

    <ups.invt.com.view.RoundRectProgressBar
    android:id="@+id/bar"
    android:layout_width="20dp"
    android:layout_height="100dp"
    android_custom:cbarRoundColor="@color/transparent"
    android_custom:cbarFillColor="@color/white"
    android_custom:cbarProgressColor="@color/bar_fill_color"
    android_custom:cbarOrientation="VERTICAL"
    android:layout_centerInParent="true"/>
    

      


    d、MainActivity.java中设置进度

    progress = (RoundRectProgressBar) findViewById(R.id.bar);
    progress.setMax(100);
    
    progress.setProgress(80);


    完!!!
    ————————————————

    参考于:https://blog.csdn.net/xialong_927/article/details/86596932

  • 相关阅读:
    托付和事件的使用
    在使用supervisord 管理tomcat时遇到的小问题
    无法安装vmware tools的解决方PLEASE WAIT! VMware Tools is currently being installed on your system. Dependin
    (转)Openlayers 2.X加载高德地图
    (转)openlayers实现在线编辑
    (转) Arcgis for js加载百度地图
    (转)Arcgis for js加载天地图
    (转) 基于Arcgis for Js的web GIS数据在线采集简介
    (转) Arcgis for js之WKT和GEOMETRY的相互转换
    (转)Arcgis for Js之Graphiclayer扩展详解
  • 原文地址:https://www.cnblogs.com/changyiqiang/p/11399187.html
Copyright © 2020-2023  润新知