zoukankan      html  css  js  c++  java
  • 自定义圆环进度条

    使用自定义控件绘制一个圆环,需要重现的方法是OnDraw()实现对view的绘制,从而输出符合自己需求的view控件
    观察圆环的组成部分:
     
    外层圆+中间百分比文字+不断变化进度的弧形圈
     
    --->分析:每一个组成部分需要的属性,构成几个关键的自定义属性
             1:外层圆的颜色
             2:弧形进度圈的颜色
             3:中间百分比文字的颜色
             4:中间百分比文字的大小
             5:圆环的宽度(作为进度弧形圈的宽度)
             6:*首页当中也有一个圆环进度,为了兼容使用首页的圆环进度,增加一个自定义属性,绘制进度弧形圈的风格(实心[Fill],空心[Stroken])
     
     
    分析完毕-->绘制步骤:
     
    1:构造方法当中初始化画笔对象,获取自定义的属性值.
     
    2:重写Ondraw方法
     
      ---2.1:绘制最外层的圆
             -关键方法canvas.drawCircle(center, center, radius, paint); //画出圆环
             *:计算半径、中心点坐标、画笔设置
            中心点坐标
            int center = getWidth() / 2; //获取圆心的x坐标
            半径:
            int radius = (int) (center - roundWidth/2) ---画图说明最容易理解
     
     
      ---2.2:绘制中间的百分比文字
            --关键方法:canvas.drawText(percent + "%", center - textWidth / 2, center + textSize / 2, paint); //画出进度百分比
                        测量画笔上的文本宽度
                        float textWidth = paint.measureText(percent + "%");
                   
             画笔设置
             绘制的文字的位置,由参数2,3的X,Y坐标值决定--圆环的中心点位置显示
             X:表示从哪开始绘制,如果你直接中心点开始绘制-->画图说明最容易理解
     
             -->正确的X=center - textWidth / 2;Y = center + textSize / 2 --(因为android坐标系与数学坐标系Y轴值是相反的,也可以画图说明,这里的textsize就可以代表高度,paint.measureText测量方法执行之后,默认的文字高度就是根据文字大小计算的,相当于wrap_content,所以textSize就是本身文字所占的高度值)
             *:绘制的进度要转换为百分比形式:int percent = (int) (((float) progress / (float) max) * 100);
     
     
      ---2.3:绘制进度弧形圈
     
            ---关键方法:canvas.drawArc(oval, 0, 360 * progress / max, false, paint);  //根据进度画圆弧
            参数解释:
            oval:绘制的弧形的范围轮廓
            0:从多少角度开始绘制
            360 * progress / max:绘制弧形扫过的角度对应的区域
            false:不包含圆心,如果是true,表示包含圆心
            paint:绘制使用的画笔
     
     
            画笔设置
            paint.setStrokeWidth(roundWidth); //设置进度弧形圈的宽度,必须保持和外层圆的StrokeWidth一致,确保弧形圈绘制的时候覆盖的范围就是外层圆的宽度
            paint.setColor(roundProgressColor); //设置进度的颜色  
            
            弧形范围计算
            RectF oval = new RectF(center - radius, center - radius, center
                    + radius, center + radius); --->画图说明最容易理解
            *:注意,因为progress是相对于100当中占比多少,而弧形总共是按照角度分成360分的,所以绘制弧形圈指定参数扫过的区域角度需要计算转换一下
            =360 * progress / max(max=100)
            
     
    最后提供一个设置进度,根据进度重新绘制圆环的方法
             
    .....圆环绘制自定义控件分析end...........................................................................|
     
    RoundProgress

    public class RoundProgress extends View {
        private Paint paint = new Paint();
        private int roundColor;
        private int roundProgressColor;
        private int textColor;
        private float textSize;
        private float roundWidth;
        private int max = 100;
        private int progress = 50;
        public RoundProgress(Context context) {
            this(context, null);
        }
        public RoundProgress(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
        public RoundProgress(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgress);
            //圆环的颜色
            roundColor = mTypedArray.getColor(R.styleable.RoundProgress_roundColor, Color.RED);
            //圆环进度的颜色
            roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgress_roundProgressColor, Color.GREEN);
            //中间进度百分比文字字符串的颜色
            textColor = mTypedArray.getColor(R.styleable.RoundProgress_textColor, Color.GREEN);
            //中间进度百分比的字符串的字体大小
            textSize = mTypedArray.getDimension(R.styleable.RoundProgress_textSize, 15);
            //圆环的宽度
            roundWidth = mTypedArray.getDimension(R.styleable.RoundProgress_roundWidth, 5);
            mTypedArray.recycle();
        }
        @Override
        protected void onDraw(Canvas canvas) {
            //第一步:绘制一个最外层的圆
            paint.setColor(roundColor);
            paint.setStrokeWidth(roundWidth);
            paint.setStyle(Paint.Style.STROKE);
            paint.setAntiAlias(true);
            int center = getWidth() / 2;
            int radius = (int) (center - roundWidth / 2);
            canvas.drawCircle(center, center, radius, paint);
            //第二步:绘制正中间的文本
            float textWidth = paint.measureText(progress + "%");
            paint.setColor(textColor);
            paint.setTextSize(textSize);
            paint.setStrokeWidth(0);
            canvas.drawText(progress + "%", center - textWidth / 2, center + textSize / 2, paint);
            //第三步:
            /**
             * 参数解释:
             * oval:绘制弧形圈所包含的矩形范围轮廓
             * 0:开始的角度
             * 360 * progress / max:扫描过的角度
             * false:是否包含圆心
             * paint:绘制弧形时候的画笔
             */
            RectF oval = new RectF(center - radius, center - radius, center + radius, center + radius);
            paint.setColor(roundProgressColor);
            paint.setStrokeWidth(roundWidth);
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawArc(oval, 0, 360 * progress / max, false, paint);
        }
        public void setProgress(int progress){
            this.progress = progress;
            if(progress>100){
                this.progress = 100;
            }
            postInvalidate();
        }
    }
    

      

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="RoundProgress">
            <attr name="roundColor" format="color"/>
            <attr name="roundProgressColor" format="color"/>
            <attr name="roundWidth" format="dimension"></attr>
            <attr name="textColor" format="color"/>
            <attr name="textSize" format="dimension"/>
        </declare-styleable>
    </resources>
    

      

      <!-- 圆环进度-->
                    <cn.wh.ui.RoundProgress
                        android:id="@+id/p_progresss"
                        android:layout_width="120dp"
                        android:layout_height="120dp"
                        app:roundColor="@android:color/darker_gray"
                        app:roundProgressColor="@android:color/holo_red_dark"
                        app:roundWidth="10dp"
                        app:textColor="#18b4ed"
                        app:textSize="20sp">
                    </cn.wh.ui.RoundProgress>
    

      

     private Runnable runnable = new Runnable() {
            @Override
            public void run() {
                int tempProgress = 0;
                try {
                    while (tempProgress <= totalProgress) {
                        pProgresss.setProgress(tempProgress);
                        tempProgress++;
                        Thread.sleep(100);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
    

      

             
     
     
     
  • 相关阅读:
    iOS项目之wifi局域网传输文件到iPhone的简单实现
    iOS项目之苹果审核被拒
    iOS项目之模拟请求数据
    nvm-window常用命令
    初探浏览器渲染原理
    node + mongodb 简单实现自己的查询接口
    快速理解_.debounce方法
    tr标签使用hover的box-shadow效果不生效
    一个简单的Node命令行程序:文件浏览
    打造丝般顺滑的 H5 翻页库(传送门)
  • 原文地址:https://www.cnblogs.com/sixrain/p/6656763.html
Copyright © 2011-2022 走看看