欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现自定义圆形进度条

程序员文章站 2024-02-28 19:51:46
今天无意中发现一个圆形进度,想想自己实现一个,如下图: 基本思路是这样的: 1.首先绘制一个实心圆 2.绘制一个白色实心的正方形,遮住实心圆 3.在圆的中心动态...

今天无意中发现一个圆形进度,想想自己实现一个,如下图:

Android实现自定义圆形进度条

基本思路是这样的:

1.首先绘制一个实心圆

2.绘制一个白色实心的正方形,遮住实心圆

3.在圆的中心动态绘制当前进度的百分比字符

4.绘制一个与之前实心圆相同颜色的空心圆

5.逐渐改变当前的百分比

6.根据百分比,逐渐改变正方形的大小,逐渐减小正方形的底部y轴的坐标,不断重绘,直到达到100%

首先看看自定义的属性

在values目录下新建attrs.xml内容如下:

定义绘制圆形的背景色,和绘制圆形的半径大小

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <attr name="circlecolor" format="color"></attr>
  <attr name="half" format="dimension"></attr>

  <declare-styleable name="mycircleimage">
    <attr name="circlecolor"></attr>
    <attr name="half"></attr>
  </declare-styleable>

</resources>


自定义视图

import android.annotation.suppresslint;
import android.content.context;
import android.content.res.typedarray;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.text.textpaint;
import android.util.attributeset;
import android.util.log;
import android.view.view;

public class circlepro extends view {

 private paint paint;
 private int circleback;//圆的背景色
 private int mschedual = 0;//用于控制动态变化
 float circlehalf; //圆的半径
 string percent = "";//绘制百分比的字符串

 @suppresslint("recycle")
 public circlepro(context context, attributeset attrs, int defstyleattr) {
 super(context, attrs, defstyleattr);
 paint = new paint();
 typedarray array = context.gettheme().obtainstyledattributes(attrs, r.styleable.mycircleimage, defstyleattr,0);
 @suppresswarnings("unused")
 int leng = array.length();
 //获取自定义的属性,这里注意是r.styleable.mycircleimage_circlecolor而不是r.attr.circlecolor
 circleback = array.getcolor(r.styleable.mycircleimage_circlecolor,color.green);
 circlehalf = array.getdimension(r.styleable.mycircleimage_half,200.f);
 system.out.println(circleback);

 }

 /**
 * 这个构造参数,当在布局文件中引用该view的时候,必须重写该构造函数
 * @param context
 * @param attrs
 */
 public circlepro(context context, attributeset attrs) {
 this(context, attrs, 0);//调用自己的构造函数

 }

 /**
 * 根据文本的
 * @param text
 * @param textsize
 * @return
 */
 public float gettextwidth(string text,float textsize) {

 textpaint textpaint = new textpaint();
 textpaint.settextsize(textsize);
 return textpaint.measuretext(text);
 }

 @override
 protected void ondraw(canvas canvas) {
 // todo auto-generated method stub
 super.ondraw(canvas);

 float height = getheight();
 float width = getwidth();
// float circlehalf = (float) (width*0.7/2);

 paint.setcolor(circleback);
 paint.setantialias(true);
 paint.setstyle(paint.style.fill);
 canvas.drawcircle(width/2,height/2,circlehalf, paint);//画实心圆

 if (mschedual <= 100) {//,如果当前进度小于100,画实心矩形
  paint.setcolor(color.white);
  canvas.drawrect(width/2-circlehalf,height/2-circlehalf,width/2+circlehalf,height/2+circlehalf - mschedual*circlehalf/50, paint);
 }

 //画当前进度的字符串
 paint.setcolor(color.black);
 paint.settextsize(30.f);
 percent = mschedual+" %";
 canvas.drawtext(percent, width/2-gettextwidth(percent,30)/2,height/2+paint.gettextsize()*3/8, paint);//字体的高度=paint.gettextsize()*3/4

 //画空心圆
 paint.setcolor(circleback);
 paint.setstyle(paint.style.stroke);
 canvas.drawcircle(width/2,height/2,circlehalf, paint);

 if (mschedual < 100) {//更改当前进度值,并重绘
  mschedual++;
  invalidate();
 }
 }
}


在activity_main.xml中,需要用到自定义的属性,首先添加命名空间: xmlns:liu=”http://schemas.android.com/apk/res/com.example.androidcirclepro”

其中liu是自定义的一个前缀,随意命名的,com.example.androidcirclepro是我们的应用的包名

activity_main.xmln内容如下:

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  xmlns:liu="http://schemas.android.com/apk/res/com.example.androidcirclepro"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".mainactivity" >

  <com.example.androidcirclepro.circlepro
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    liu:half="90dp"
    liu:circlecolor="#fff0f0"
    />

</relativelayout>


至此一个自定义的圆形进度条就完成了,是不是很简单。