自定义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软件编程有所帮助。

(0)

相关推荐

  • Android自定义水平进度条的圆角进度

    平时项目中经常用到自定义进度条样式,我们一般实现的也是下面的第一种,至于第二种的圆角进度,网上介绍的资料也不是很多,这里一起展示一下这两种的实现. 下面开始看代码,先从主界面布局开始看起: <ProgressBar style="@android:style/Widget.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="20dp&qu

  • Android应用中炫酷的横向和环形进度条的实例分享

    一.概述 最近需要用进度条,秉着不重复造轮子的原则,上github上搜索了一番,看了几个觉得比较好看的ProgressBar,比如:daimajia的等.简单看了下代码,基本都是继承自View,彻彻底底的自定义了一个进度条.盯着那绚丽滚动条,忽然觉得,为什么要通过View去写一个滚动条,系统已经提供了ProgressBar以及属于它的特性,我们没必要重新去构建一个,但是系统的又比较丑,不同版本变现还不一定一样.那么得出我们的目标:改变系统ProgressBar的样子. 对没错,我们没有必要去从0

  • 实例详解Android自定义ProgressDialog进度条对话框的实现

    Android SDK已经提供有进度条组件ProgressDialog组件,但用的时候我们会发现可能风格与我们应用的整体风格不太搭配,而且ProgressDialog的可定制行也不太强,这时就需要我们自定义实现一个ProgressDialog. 通过看源码我们发现,ProgressDialog继承自Alertdialog,有一个ProgressBar和两个TextView组成的,通过对ProgressDialog的源码进行改进就可以实现一个自定义的ProgressDialog. 1.效果: 首先

  • Android中自定义进度条详解

    Android原生控件只有横向进度条一种,而且没法变换样式,比如原生rom的样子 很丑是吧,当伟大的产品设计要求更换前背景,甚至纵向,甚至圆弧状的,咋办,比如: ok,我们开始吧: 一)变换前背景 先来看看progressbar的属性: 复制代码 代码如下: <ProgressBar             android:id="@+id/progressBar"             style="?android:attr/progressBarStyleHor

  • 自定义Android圆形进度条(附源码)

    本文实例讲述了Android自定义圆形进度条,分享给大家供大家参考.具体如下: 运行效果截图如下: 具体代码如下: 自定义的View: import com.example.circlepregress.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import andr

  • Android自定义进度条的圆角横向进度条实例详解

    1.本文将向你介绍自定义进度条的写法,比较简单,但还是有些知识点是需要注意的: invalidate()方法 RectF方法的应用 onMeasure方法的应用 2.原理 画3层圆角矩形,底层为黑色,第二层为灰色,最上一层为进度条颜色,示例图如下: 3.效果图   实现圆角进度条还有很多其他方法,比如在Progress控件里填充圆角图片,通过拉伸图片来达到预想的效果,虽然听起来很简单,但实现起来还是有些麻烦的. 4.解说方法 (1)invalidate()方法 invalidate()是用来刷新

  • android自定义进度条渐变圆形

    在安全卫生上,经常看到有圆形的进度条在转动,效果非常好看,于是就尝试去实现一下,具体实现过程不多说了,直接上效果图,先炫耀下. 效果图: 分析:比较常见于扫描结果.进度条等场景 利用canvas.drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)绘制圆弧 Paint的一些属性定义粗细.颜色.样式等 LinearGradient实现颜色的线型渐变 同样的道理,可以画出长条进度

  • Android 自定义ProgressDialog进度条对话框用法详解

    ProgressDialog的基本用法 ProgressDialog为进度对话框.android手机自带的对话框显得比较单一,我们可以通过ProgressDialog来自己定义对话框中将要显示出什么东西. 首先看看progressDialog里面的方法 setProgressStyle:设置进度条风格,风格为圆形,旋转的. setTitlt:设置标题 setMessage:设置提示信息: setIcon:设置标题图标: setIndeterminate:设置ProgressDialog 的进度条

  • android自定义进度条渐变色View的实例代码

    最近在公司,项目不是很忙了,偶尔看见一个兄台在CSDN求助,帮忙要一个自定义的渐变色进度条,我当时看了一下进度条,感觉挺漂亮的,就尝试的去自定义view实现了一个,废话不说,先上图吧! 这个自定义的view,完全脱离了android自带的ProgressView,并且没使用一张图片,这样就能更好的降低程序代码上的耦合性! 下面我贴出代码  ,大概讲解一下实现思路吧! 复制代码 代码如下: package com.spring.progressview; import android.conten

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

    本文实例讲述了Android自定义圆形进度条,分享给大家供大家参考.具体如下: 大家也可以参考这两篇文章进行学习: <自定义Android圆形进度条(附源码)>   <Android带进度的圆形进度条> 运行效果截图如下: 主要代码: package com.sxc.hexagonprogress; import java.util.Random; import android.content.Context; import android.content.res.ColorSta

  • jQuery 自定义下拉框(DropDown)附源码下载

    先给大家展示下效果图,喜欢的朋友可以下载源码哦 效果演示   源码下载 <section class="main"> <div class="wrapper-demo"> <div id="dd" class="wrapper-dropdown-1" tabindex="1"> <span>手册网</span> <ul class="

  • 简单实现Android学生管理系统(附源码)

    本文实例讲述了Android实现学生管理系统,分享给大家供大家参考.具体如下: (1)管理系统实现的功能主要是:学生.教师的注册登录,和选课,以及修改学生的成绩等基本简单的功能,最主要的是实现一些Dialog的使用. 界面如下: (2)主要代码如下:(个人留作笔记,如需要完整代码,在最下边免费下载) 下边是一个适配器,适配器是为了一个listvie进行设置值,其中加载的是一个itemview,适配器中还是用了继承的方法,用于通知适配器进行更新. public class CourseAdapte

  • Android实现中国象棋附源码下载

    象棋,很多人多接触过,学者写了一个,大神可以指点一下~直接上代码: 贴出主要代码,想要Demo的点击下载:中国象棋Demo package wyf.ytl; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; impor

  • Android自定义多节点进度条显示的实现代码(附源码)

    亲们里面的线段颜色和节点图标都是可以自定义的. 在没给大家分享实例代码之前,先给大家展示下效果图: main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rl_parent" xmlns:tools="http://schemas.android.com/tools" android:layou

  • Android编程实现画板功能的方法总结【附源码下载】

    本文实例讲述了Android编程实现画板功能的方法.分享给大家供大家参考,具体如下: Android实现画板主要有2种方式,一种是用自定义View实现,另一种是通过Canvas类实现.当然自定义View内部也是用的Canvas.第一种方式的思路是,创建一个自定义View(推荐SurfaceView),在自定义View里通过Path对象记录手指滑动的路径调用lineTo()绘制:第二种方式的思路是,先用Canvas绘制一张空的Bitmap,通过ImageView的setImageBitmap()方

  • Android自定义View实现进度条动画

    本文实例为大家分享了Android自定义View实现进度条动画的具体代码,供大家参考,具体内容如下 控件效果 原理: 控制代码/ /更新进度值 val mHandler = object : Handler() {         override fun handleMessage(msg: Message?) {             progressView.setCurrentProgress(progress1.toFloat())         }     } //开启动画,更新

  • jquery自定义插件结合baiduTemplate.js实现异步刷新(附源码)

    上一篇记录了BaiduTemplate模板引擎使用示例(附源码),在此基础上对使用方法进行了封装 自定义插件jajaxrefresh.js 代码如下: //闭包限定命名空间 (function ($) { $.fn.extend({ "ajaxrefresh": function (options) { //检测用户传进来的参数是否合法 if (!isValid(options)) return this; var opts = $.extend({}, defaluts, optio

  • Android 自定义view实现进度条加载效果实例代码

    这个其实很简单,思路是这样的,就是拿view的宽度,除以点的点的宽度+二个点 之间的间距,就可以算出大概能画出几个点出来,然后就通过canvas画出点,再然后就是每隔多少时间把上面移动的点不断的去改变它的坐标就可以, 效果如下: 分析图: 代码如下: package com.example.dotloadview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bit

随机推荐