当前位置: 移动技术网 > 移动技术>移动开发>Android > 自定义Android六边形进度条(附源码)

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

2019年07月24日  | 移动技术网移动技术  | 我要评论
本文实例讲述了android自定义圆形进度条,分享给大家供大家参考。具体如下: 大家也可以参考这两篇文章进行学习: 《自定义android圆形进度条(附源码)》&nb

本文实例讲述了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软件编程有所帮助。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网