自定义Progressbar

作者: GeekGray | 来源:发表于2018-10-02 22:55 被阅读163次

    阅读原文

    绘制圆环,圆弧,文本

    image
        /**
         * canvas:画布,对应着视图在布局中的范围区间。范围的左上顶点即为坐标原点
         *
         * @param canvas
         */
        @Override
        protected void onDraw(Canvas canvas)
        {
            //1.绘制圆环
            //获取圆心坐标
            int cx = width / 2;
            int cy = width / 2;
            float radius = width / 2 - roundWidth / 2;
            paint.setColor(roundColor);//设置画笔颜色
            paint.setStyle(Paint.Style.STROKE);//设置圆环的样式
            paint.setStrokeWidth(roundWidth);//设置圆环的宽度
            canvas.drawCircle(cx, cy, radius, paint);
    
            //2.绘制圆弧
            RectF rectF = new RectF(roundWidth / 2, roundWidth / 2, width - roundWidth / 2, width - roundWidth / 2);
            paint.setColor(roundProgressColor);//设置画笔颜色
            canvas.drawArc(rectF, 0, progress * 360 / max, false, paint);
    
            //3.绘制文本
            String text = progress * 100 / max + "%";
            //设置paint
            paint.setColor(textColor);
            paint.setTextSize(textSize);
            paint.setStrokeWidth(0);
            Rect rect = new Rect();//创建了一个矩形,此时矩形没有具体的宽度和高度
            paint.getTextBounds(text, 0, text.length(), rect);//此时的矩形的宽度和高度即为整好包裹文本的矩形的宽高
            //获取左下顶点的坐标
            int x = width / 2 - rect.width() / 2;
            int y = width / 2 + rect.height() / 2;
    
    
            canvas.drawText(text, x, y, paint);
    
        }
    

    使用自定义属性

    1. 什么是自定义属性?

    定义可以在布局文件的标签中使用的属性。

    2. 为什么要自定义视图属性?

    这样就可以通过布局的方式给视图对象指定特定的属性值, 而不用动态的设置

    3. 理解属性值的类型(format)

     1. reference 引用类型值 :@id/...
    
     2. color 颜色类型值  #ff00ff
    
     3. boolean 布尔类型值 true false
    
     4. dimension 尺寸类型值 dp / px /sp
    
     5.  integer 整数类型值  weight  progress max
    
     6. float 小数类型值  0.5f
    
     7. string 字符串类型值  ""
    
     8. <enum> 枚举类型值 :水平/垂直
    

    4. 在values目录下创建attrs.xml

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

    5. 在fragment_home.xml布局文件中引用自定义属性

    在布局文件中引用当前应用的名称空间

    //P2PInvest可随意命名,引用一致即可
    xmlns:P2PInvest="http://schemas.android.com/apk/res-auto"
    

    6. 使用自定义的圆形进度条和自定义属性

    <com.example.p2pinvest.ui.RoundProgress
                    android:id="@+id/roundPro_home"
                    android:layout_width="120dp"
                    android:layout_height="120dp"
                    android:layout_marginTop="10dp"
                    P2PInvest:roundColor="@color/more_text"
                    P2PInvest:roundProgressColor="@color/round_red_common"
                    P2PInvest:textColor="@color/title_back"
                    P2PInvest:textSize="20dp"
                    P2PInvest:roundWith="10dp"
                    P2PInvest:max="100"
                    P2PInvest:progress="70"
                    />
    

    7. 在自定义View类的构造方法中, 取出布局中的自定义属性值

     public RoundProgress(Context context, AttributeSet attrs, int defStyleAttr)
        {
            super(context, attrs, defStyleAttr);
    
            //初始化画笔
            paint = new Paint();
            paint.setAntiAlias(true);//去除毛边
    
            //获取自定义的属性
            //1.获取TypeArray的对象(调用两个参数的方法)
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgress);
    
            //2.取出所有的自定义属性
            roundColor = typedArray.getColor(R.styleable.RoundProgress_roundColor, Color.GRAY);
            roundProgressColor = typedArray.getColor(R.styleable.RoundProgress_roundProgressColor, Color.RED);
            textColor = typedArray.getColor(R.styleable.RoundProgress_textColor, Color.GREEN);
            roundWidth = typedArray.getDimension(R.styleable.RoundProgress_roundWith, UIUtils.dp2px(10));
            textSize = typedArray.getDimension(R.styleable.RoundProgress_textSize, UIUtils.dp2px(20));
            max = typedArray.getInteger(R.styleable.RoundProgress_max, 100);
            progress = typedArray.getInteger(R.styleable.RoundProgress_progress, 30);
    
            //3.回收处理
            typedArray.recycle();
        }
    

    8. 让圆环进度"动起来"

    1.自定义RoundProgress类中提供进度属性的getter和setter方法

    2.在HomeFragment的onSuccess()中:

    totalProgress = Integer.parseInt(index.product.progress);
    
    new Thread(runnable).start();
    

    其中,属性runnable声明为:

    //进度条的加载
    private Runnable runnable = new Runnable()
        {
            @Override
            public void run()
            {
                roundProHome.setMax(100);
                for (int i = 0; i < currentProress; i++)
                {
                    roundProHome.setProgress(i + 1);
    
                    SystemClock.sleep(20);
                    //强制重绘
    //                roundProHome.invalidate();//只有主线程才可以如此调用
                    roundProHome.postInvalidate();//主线程、分线程都可以如此调用
                }
            }
        };
    

    相关文章

      网友评论

        本文标题:自定义Progressbar

        本文链接:https://www.haomeiwen.com/subject/bpoaoftx.html