018android初级篇之自定义圆形进度条

项目需要,需要一个圆形的进度条,所想到的实现方案是这样的: 自定义View,订制一个圆形的进度条。下面简述实现,有不当之处敬请指正。

主题思想

  1. 自定义类继承自View,在构造函数中,获得从配置文件中获得的自定义属性值。
  2. 在onDraw中绘制,跟据获得的属性值,绘制想要的图形。

自定义属性的定义

在文件attrs.xml中

<resources>
    <declare-styleable name="RoundProgressBar">  
        <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" /> 
        <attr name="max" format="integer"></attr> 
        <attr name="textIsDisplayable" format="boolean"></attr>
        <attr name="style">
            <enum name="STROKE" value="0"></enum>
            <enum name="FILL" value="1"></enum>
        </attr>
    </declare-styleable> 
</resources>

则,在layout文件中,可以使用这些自定义属性:

<com.running.aid.aidrunning.RoundProgressBar
    android:id="@+id/roundProgressBar"
    android:layout_width="250dip"
    android:layout_height="250dip"
    android:layout_alignParentTop="true"
    android:layout_marginBottom="78dp"
    android:layout_centerHorizontal="true"


    android_custom:roundColor="#D1D1D1"
    android_custom:roundProgressColor="@android:color/holo_green_light"
    android_custom:textColor="@color/gray9"
    android_custom:roundWidth="25dip"
    android_custom:textSize="18sp" />

在自定义的进度条类的构造函数中,获取配置的自定义属性值:

roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED);
roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.GREEN);
textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);
roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth, 5);
max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100);
textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);
style = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0);

绘制控件

画最外层的大圆环

    int centre = getWidth()/2; //获取圆心的x坐标
    int radius = (int) (centre - roundWidth/2); //圆环的半径
    paint.setColor(roundColor); //设置圆环的颜色
    paint.setStyle(Paint.Style.STROKE); //设置空心
    paint.setStrokeWidth(roundWidth); //设置圆环的宽度
    paint.setAntiAlias(true);  //消除锯齿
    canvas.drawCircle(centre, centre, radius, paint); //画出圆环

绘制文本

这里是模仿计步器,显示的当前步数,总步数,分三行显示。

paint.setStrokeWidth(0);
paint.setColor(textColor);
paint.setTextSize(textSize);
paint.setTypeface(Typeface.DEFAULT_BOLD); //设置字体

//if(textIsDisplayable && percent != 0 && style == STROKE){
if(textIsDisplayable && style == STROKE){
    stepNumValueStr = "" + currentValue;
    stepAIMValueStr = "" + maxValue;
    float stepNumStrWidth = paint.measureText(stepNumStr);
    
    float stepAIMStrWidth = paint.measureText(stepAIMStr+stepAIMValueStr);
    float y = paint.getFontMetrics().bottom - paint.getFontMetrics().top;
    canvas.drawText(stepNumStr,centre-stepNumStrWidth/2,centre -2*y,paint);
    canvas.drawText(stepAIMStr+stepAIMValueStr,centre-stepAIMStrWidth/2,centre+2*y,paint);
    
    paint.setTextSize(textSize * 2);
    paint.setColor(getResources().getColor(R.color.blue6));
    float stepNumValueStrWidth = paint.measureText(stepNumValueStr);
    canvas.drawText(stepNumValueStr,centre-stepNumValueStrWidth/2,centre,paint);


}

绘制扇形,进度条

    paint.setStrokeWidth(roundWidth); //设置圆环的宽度
    paint.setColor(roundProgressColor);  //设置进度的颜色
    RectF oval = new RectF(centre - radius, centre - radius, centre
            + radius, centre + radius);  //用于定义的圆弧的形状和大小的界限

    switch (style) {
        case STROKE:{
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawArc(oval, 0, 360 * progress / max, false, paint);  //根据进度画圆弧
            break;
        }
        case FILL:{
            paint.setStyle(Paint.Style.FILL_AND_STROKE);
            if(progress !=0)
                canvas.drawArc(oval, 0, 360 * progress / max, true, paint);  //根据进度画圆弧
            break;
        }
    }

参考链接

  1. 017android初级篇之android canvas的使用
  2. Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏钟绍威的专栏

怎么改变按钮的图标

按钮的图标一开始很难看 所以要改 改变按钮图标的方法: javax.swing.AbstractButton中的方法 setContentAreaF...

237100
来自专栏极乐技术社区

『Demo』你想开发的页面特效,这里都能找到~

来源 | 微信小程序联盟 作者 | 极乐蜀黍 这期极乐大叔将小程序内各种页面效果实现方法聚合了一下,以便大家能够迅速而方便的使用。 1 文字跑马灯效果: h...

33780
来自专栏前端之路

–探索CSS3动画、过渡

16550
来自专栏7号代码

Android应用界面开发——布局

线性布局可以控制各组件横向排列(通过设置属性android:orientation属性控制),也可控制各组件纵向排列。

25720
来自专栏性能与架构

CSS选择器是如何确定优先级的?

先看下面的示例 <div id="content"> <p id="title">Hello world</p> </div> 有如下的2个css选择器...

316100
来自专栏移动开发

PullBezierZoomView 一个具有贝塞尔曲线下拉效果的自定义view

该控件效果基于PullZoomView源码改动的而来,感谢Frank-Zhu的开源代码.该控件具有下拉放大背景图和贝塞尔曲线的效果.

12550
来自专栏Android开发指南

自定义圆环进度条

44960
来自专栏IMWeb前端团队

Canvas实现progress效果

据说本贵族圈每月不分享就邀请雪糕。。。所以分享下一个简单的Canvas插件   Canvas元素是HTML5的一部分,允许脚本语言动态渲染位图像,你可以使用j...

27970
来自专栏木子昭的博客

<jQury动态布局>浮动子元素均分布局对应的完整源码,以及jQuery在这里

在前端页面的布局过程中,作者遇到了,这样一个问题 当子元素为浮动元素时,父元素设置相应属性后可以被子元素撑开,但无法实现子元素的均分布局,在网络上找了半小时...

308100
来自专栏Android小菜鸡

自定义View学习之路(二)————Paint与Canvas

  Canvas可以理解为画布,配置好画笔后,我们可以调用Canvas的各种绘制方法。   绘制直线:canvas.drawLine(float startX...

11010

扫码关注云+社区

领取腾讯云代金券