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

自定义Android六边形进度条(附源码)

程序员文章站 2024-02-17 09:37:46
本文实例讲述了android自定义圆形进度条,分享给大家供大家参考。具体如下: 大家也可以参考这两篇文章进行学习: 《自定义android圆形进度条(附源码)》&nb...

本文实例讲述了android自定义圆形进度条,分享给大家供大家参考。具体如下:

大家也可以参考这两篇文章进行学习: 《自定义android圆形进度条(附源码)》   《android带进度的圆形进度条》

运行效果截图如下:

自定义Android六边形进度条(附源码)

主要代码:

package com.sxc.hexagonprogress;

import java.util.random;
import android.content.context;
import android.content.res.colorstatelist;
import android.content.res.resources;
import android.content.res.typedarray;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.graphics.paintflagsdrawfilter;
import android.graphics.path;
import android.graphics.rectf;
import android.graphics.typeface;
import android.util.attributeset;
import android.util.log;
import android.view.view;


/**
 * 六边形带进度的进度条,线程安全的view,可直接在线程中更新进度
 * 
 * @author sunxunchao
 *
 */
public class hexagonprogress extends view {
 /**
  * 画笔对象的引用
  */
 private paint paint, mpaint;

 /**
  * 画笔路径
  */
 private path path, mpath;

 /**
  * 环的颜色
  */
 private int roundcolor;

 /**
  * 环进度的颜色
  */
 private int roundprogresscolor;

 /**
  * 中间进度百分比的字符串的颜色
  */
 private int textcolor;

 /**
  * 中间进度百分比的字符串的字体
  */
 private float textsize;

 /**
  * 环的宽度
  */
 private float roundwidth;

 /**
  * 最大进度
  */
 private double max;

 /**
  * 当前进度
  */
 private double progress;
 /**
  * 是否显示中间的进度
  */
 private boolean textisdisplayable;

 /**
  * 进度的风格,实心或者空心
  */
 private int style;

 public static final int stroke = 0;
 public static final int fill = 1;

 public hexagonprogress(context context) {
  this(context, null);
 }

 public hexagonprogress(context context, attributeset attrs) {
  this(context, attrs, 0);
 }

 public hexagonprogress(context context, attributeset attrs, int defstyle) {
  super(context, attrs, defstyle);

  paint = new paint();
  mpaint = new paint();

  typedarray mtypedarray = context.obtainstyledattributes(attrs,
    r.styleable.hexagonprogressbar);

  // 获取自定义属性和默认值
  roundcolor = mtypedarray.getcolor(
    r.styleable.hexagonprogressbar_hexagoncolor, color.red);
  roundprogresscolor = mtypedarray.getcolor(
    r.styleable.hexagonprogressbar_hexagonprogresscolor, color.green);
  textcolor = mtypedarray.getcolor(
    r.styleable.hexagonprogressbar_textcolor, color.green);
  textsize = mtypedarray.getdimension(
    r.styleable.hexagonprogressbar_textsize, 15);
  roundwidth = mtypedarray.getdimension(
    r.styleable.hexagonprogressbar_hexagonwidth, 5);
  max = mtypedarray.getinteger(r.styleable.hexagonprogressbar_max, 100);
  textisdisplayable = mtypedarray.getboolean(
    r.styleable.hexagonprogressbar_textisdisplayable, true);

  mtypedarray.recycle();
 }

 @override
 protected void ondraw(canvas canvas) {
  super.ondraw(canvas);

  /**
   * 画外六边形
   */
  int centre = getwidth() / 2;// 中心坐标
  int radius = (int) (centre - roundwidth / 2);// 六边形边长
  mpaint.setcolor(roundcolor); // 设置圆环的颜色
  mpaint.setstyle(paint.style.stroke); // 设置空心
  mpaint.setstrokewidth(roundwidth); // 设置圆环的宽度
  mpaint.setantialias(true); // 消除锯齿
  mpath = new path();//设置路径
  // 第一个点坐标(centre-radius, getheight()/2)
  // 第二个点坐标(centre-radius/2,getheight()/2-math.sqrt(3)*radius/2)
  // 第三个点坐标(centre+radius/2,getheight()/2-math.sqrt(3)*radius/2)
  // 第四个点坐标(centre+radius,getheight()/2)
  // 第五个点坐标 (centre+radius/2,math.sqrt(3)*radius/2+getheight()/2)
  // 第六个点坐标 (centre-radius/2,math.sqrt(3)*radius/2+getheight()/2)
  mpath.moveto(centre - radius, centre); // a
  mpath.lineto(centre - radius / 2, (float) (centre - math.sqrt(3)* radius / 2));// b
  mpath.lineto(centre + radius / 2, (float) (centre - math.sqrt(3)* radius / 2));// c
  mpath.lineto(centre + radius, centre);// d
  mpath.lineto(centre + radius / 2,(float) ((math.sqrt(3) * radius / 2) + centre));// e
  mpath.lineto(centre - radius / 2,(float) ((math.sqrt(3) * radius / 2) + centre));// f
  mpath.close();
  canvas.drawpath(mpath, mpaint);

  /**
   * 画进度百分比
   */
  mpaint.setstrokewidth(0);
  mpaint.setcolor(textcolor);
  mpaint.settextsize(textsize);
  mpaint.settypeface(typeface.default_bold); // 设置字体
  int percent = (int) (((float) progress / (float) max) * 100); // 中间的进度百分比,先转换成float在进行除法运算,不然都为0
  float textwidth = mpaint.measuretext(percent + "%"); // 测量字体宽度,我们需要根据字体的宽度设置在圆环中间

  if (textisdisplayable && style == stroke) {
   canvas.drawtext(percent + "%", centre - textwidth / 2, centre
     + textsize / 2, mpaint); // 画出进度百分比
  }

  /**
   * 画六边形进度
   */

  path = new path();
  paint.setstrokewidth(roundwidth); // 设置圆环的宽度
  paint.setcolor(roundprogresscolor); // 设置进度的颜色
  paint.setantialias(true);

  double k= (progress*6) / max;

  paint.setstyle(paint.style.stroke);
   if (k <= 1|| k==0) {
    path.moveto(centre + radius, centre);
    path.lineto((float)(centre+radius-k*radius/2), (float) (centre+k*radius*math.sqrt(3)/2));
   } 
   else if (k>1&&k<=2) {
    path.moveto(centre + radius, centre); 
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto((float) (centre+1.5*radius-k*radius), (float) (centre+0.5*math.sqrt(3)*radius));
   }else if (k>2&&k<=3) {
    path.moveto(centre + radius, centre); 
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto((float)(centre+0.5*radius-0.5*radius*k), (float) (centre+1.5*math.sqrt(3)*radius-0.5*k*radius*math.sqrt(3)));
   }else if (k>3&&k<=4) {
    path.moveto(centre + radius, centre); 
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre-radius, centre);
    path.lineto((float)(centre-radius+0.5*k*radius-1.5*radius), (float) (centre-0.5*(k-3)*radius*math.sqrt(3)));
   }else if (k>4&&k<=5) {
    path.moveto(centre + radius, centre); 
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius, centre);
    path.lineto(centre - radius / 2, (float) (centre - math.sqrt(3)* radius / 2));
    path.lineto((float) ((k-4)*radius+centre-0.5*radius),(float) (centre - math.sqrt(3)* radius / 2));
   }else if (k>5&&k<6) {
    path.moveto(centre + radius, centre); 
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius, centre);
    path.lineto(centre - radius / 2, (float) (centre - math.sqrt(3)* radius / 2));
    path.lineto(centre + radius / 2,(float) (centre - math.sqrt(3)* radius / 2));
    path.lineto((float)(centre+0.5*radius+0.5*(k-5)*radius),(float) (centre-0.5*math.sqrt(3)*radius+0.5*math.sqrt(3)*(k-5)*radius));
   }else {
    path.moveto(centre + radius, centre); 
    path.lineto(centre + radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius / 2, (float) ((math.sqrt(3) * radius / 2) + centre));
    path.lineto(centre - radius, centre);
    path.lineto(centre - radius / 2, (float) (centre - math.sqrt(3)* radius / 2));
    path.lineto(centre + radius / 2,(float) (centre - math.sqrt(3)* radius / 2));
    path.lineto(centre + radius , centre);
    path.close();
   }

   canvas.drawpath(path, paint);

 }

 public synchronized double getmax() {
  return max;
 }

 /**
  * 设置进度的最大值
  * 
  * @param max
  */
 public synchronized void setmax(int max) {
  if (max < 0) {
   throw new illegalargumentexception("max not less than 0");
  }
  this.max = max;
 }

 /**
  * 获取进度.需要同步
  * 
  * @return
  */
 public synchronized double getprogress() {
  return progress;
 }

 /**
  * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步 刷新界面调用postinvalidate()能在非ui线程刷新
  * 
  * @param progress
  */
 public synchronized void setprogress(double progress) {
  if (progress < 0) {
   throw new illegalargumentexception("progress not less than 0");
  }
  if (progress > max) {
   progress = max;
  }
  if (progress <= max) {
   this.progress = progress;
   postinvalidate();
  }

 }

 public int getcriclecolor() {
  return roundcolor;
 }

 public void setcriclecolor(int criclecolor) {
  this.roundcolor = criclecolor;
 }

 public int getcricleprogresscolor() {
  return roundprogresscolor;
 }

 public void setcricleprogresscolor(int cricleprogresscolor) {
  this.roundprogresscolor = cricleprogresscolor;
 }

 public int gettextcolor() {
  return textcolor;
 }

 public void settextcolor(int textcolor) {
  this.textcolor = textcolor;
 }

 public float gettextsize() {
  return textsize;
 }

 public void settextsize(float textsize) {
  this.textsize = textsize;
 }

 public float getroundwidth() {
  return roundwidth;
 }

 public void setroundwidth(float roundwidth) {
  this.roundwidth = roundwidth;
 }

}

在values中新建一个attrs.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="hexagonprogressbar"> 
  <attr name="hexagoncolor" format="color"/>
  <attr name="hexagonprogresscolor" format="color"/>
  <attr name="hexagonwidth" 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>

项目免费下载: 《android六边形进度条》

希望本文所述对大家学习android软件编程有所帮助。