热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

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

这篇文章主要介绍了android自定义进度条渐变色View的实例代码,有需要的朋友可以参考一下

最近在公司,项目不是很忙了,偶尔看见一个兄台在CSDN求助,帮忙要一个自定义的渐变色进度条,我当时看了一下进度条,感觉挺漂亮的,就尝试的去自定义view实现了一个,废话不说,先上图吧!

 

这个自定义的view,完全脱离了android自带的ProgressView,并且没使用一张图片,这样就能更好的降低程序代码上的耦合性!

下面我贴出代码  ,大概讲解一下实现思路吧!

代码如下:

package com.spring.progressview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;

/***
 * 自定义进度条
 * @author spring sky
 * Email:vipa1888@163.com
 * 创建时间:2014-1-6下午3:28:51
 */
public class SpringProgressView extends View {

 /**分段颜色*/
 private static final int[] SECTION_COLORS = {Color.GREEN,Color.YELLOW,Color.RED};
 /**进度条最大值*/
 private float maxCount;
 /**进度条当前值*/
 private float currentCount;
 /**画笔*/
 private Paint mPaint;
 private int mWidth,mHeight;

 public SpringProgressView(Context context, AttributeSet attrs,
   int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  initView(context);
 }

 public SpringProgressView(Context context, AttributeSet attrs) {
  super(context, attrs);
  initView(context);
 }

 public SpringProgressView(Context context) {
  super(context);
  initView(context);
 }

 private void initView(Context context) {
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  mPaint = new Paint();
  mPaint.setAntiAlias(true);
  int round = mHeight/2;
  System.out.println("max="+maxCount + "  current="+currentCount);
  mPaint.setColor(Color.rgb(71, 76, 80));
  RectF rectBg = new RectF(0, 0, mWidth, mHeight);
  canvas.drawRoundRect(rectBg, round, round, mPaint);
  mPaint.setColor(Color.BLACK);
  RectF rectBlackBg = new RectF(2, 2, mWidth-2, mHeight-2);
  canvas.drawRoundRect(rectBlackBg, round, round, mPaint);

  float section = currentCount/maxCount;
  RectF rectProgressBg = new RectF(3, 3, (mWidth-3)*section, mHeight-3);
  if(section <= 1.0f/3.0f){
   if(section != 0.0f){
    mPaint.setColor(SECTION_COLORS[0]);
   }else{
    mPaint.setColor(Color.TRANSPARENT);
   }
  }else{
   int count = (section <= 1.0f/3.0f*2 ) ? 2 : 3;
   int[] colors = new int[count];
   System.arraycopy(SECTION_COLORS, 0, colors, 0, count);
   float[] positiOns= new float[count];
   if(count == 2){
    positions[0] = 0.0f;
    positions[1] = 1.0f-positions[0];
   }else{
    positions[0] = 0.0f;
    positions[1] = (maxCount/3)/currentCount;
    positions[2] = 1.0f-positions[0]*2;
   }
   positions[positions.length-1] = 1.0f;
   LinearGradient shader = new LinearGradient(3, 3, (mWidth-3)*section, mHeight-3, colors,null, Shader.TileMode.MIRROR);
   mPaint.setShader(shader);
  }
  canvas.drawRoundRect(rectProgressBg, round, round, mPaint);
 }

 private int dipToPx(int dip) {
  float scale = getContext().getResources().getDisplayMetrics().density;
  return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
 }

 /***
  * 设置最大的进度值
  * @param maxCount
  */
 public void setMaxCount(float maxCount) {
  this.maxCount = maxCount;
 }

 /***
  * 设置当前的进度值
  * @param currentCount
  */
 public void setCurrentCount(float currentCount) {
  this.currentCount = currentCount > maxCount ? maxCount : currentCount;
  invalidate();
 }

 public float getMaxCount() {
  return maxCount;
 }

 public float getCurrentCount() {
  return currentCount;
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
  int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
  int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
  int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
  if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {
   mWidth = widthSpecSize;
  } else {
   mWidth = 0;
  }
  if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {
   mHeight = dipToPx(15);
  } else {
   mHeight = heightSpecSize;
  }
  setMeasuredDimension(mWidth, mHeight);
 }
 


}


以上代码就是该控件的全部核心代码了
具体思路:
1.进度条,其实就是一个最大值和最小值的比例值,这个比例就是 当前值/最大值;
2.自定义的圆角问题,只要还是用到了Canvar的画板的drawRoundRect ;
3.渐变色:LinearGradient对象渲染,具体渲染的比例要自己计算,目前我的程序提供3中颜色渲染,具体规则是:
(1)当进度条占最大值的三分之一以下,则提供一种颜色
   (2)当最大值超过三分之一话,就区分是否超过三分之二,如果超过则用三种,否则用两种颜色,因为三种颜色各占总进度条的三分之一,这是一个初中数据的问题,自己慢慢画图吧!
4.怎么把进度条放在一个有圆角背景的上面,这个就是绘制两个圆角长方形:第一个作为背景,第二个作为进度条的实体,具体第二个进度的实体占多长,就是当前 currentCount/maxCount*自定义View的长度   ;


其他的,没啥技术难点了,做这种自定义控件,最重要的是,自定要根据人家的效果图,看懂实现思路,具体代码简历在思路上的,否则只会纸上谈兵!如果看不懂,就要多画图,具体的一步步计算,天长地久,也就能“练”出来了!

下面提供一个demo下载地址:http://xiazai.jb51.net/201401/yuanma/SpringProgressDemo(jb51.net).zip


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 【Windows】实现微信双开或多开的方法及步骤详解
    本文介绍了在Windows系统下实现微信双开或多开的方法,通过安装微信电脑版、复制微信程序启动路径、修改文本文件为bat文件等步骤,实现同时登录两个或多个微信的效果。相比于使用虚拟机的方法,本方法更简单易行,适用于任何电脑,并且不会消耗过多系统资源。详细步骤和原理解释请参考本文内容。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
author-avatar
饥饿的饮水机
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有