1. 程式人生 > >Android自定義漸變色ProgressBar

Android自定義漸變色ProgressBar

效果圖

廢話不多說,直接上一張
效果圖

gif圖有點暗,可能是截圖軟體的原因,來個靜態的效果,裡面是有個背景的噢

靜態

簡單介紹

一個圓角的漸變色progress的效果,載入時能從0增長到targetCount(如果需要改變顏色,直接在
private static final int[] SECTION_COLORS = {Color.parseColor("#FF62EBEE"), Color.parseColor("#FF50E2FB"), Color.parseColor("#FF4CE1FD")};
這裡改下就ok了,自定義你懂得,自己改改就好了)

如何用這個效果

  1. 在xml中使用該自定義控制元件
  2. 設定最大值setMaxCount(float maxCount)
  3. 設定當前顯示值setTargetCount(float targetCount)

上程式碼


import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import
android.graphics.RectF; import android.graphics.Shader; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.AttributeSet; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; /*** * 自定義進度條 * * @author spring sky * Email:
[email protected]
* 建立時間:2014-1-6下午3:28:51 * @updatedauthor stefan * 修改時間:2016-12-19下午1:43:03 */
public class SpringProgressView extends View { /** * 分段顏色 */ private static final int[] SECTION_COLORS = {Color.parseColor("#FF62EBEE"), Color.parseColor("#FF50E2FB"), Color.parseColor("#FF4CE1FD")}; /** * 進度條最大值 */ private float maxCount; /** * 進度條當前值 */ private float currentCount = 0; /** * 目標值 */ private float targetCount; private int mBackGroundColor = Color.parseColor("#26000000"); /** * 當前背景寬 */ private float mCurrentBgWidth = 0; /** * 當前背景高度 */ private float mCurrentBgHeight = 0; /** * 畫筆 */ private Paint mPaint, mBgPaint; private int mWidth, mHeight; float speed = 20f, bgSpeed = 2f; private Object[] mLock = new Object[]{}; private boolean needShowBgAnimDelay; private long DURATION; 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) { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(Color.rgb(71, 76, 80)); mBgPaint = new Paint(); mBgPaint.setAntiAlias(true); mBgPaint.setColor(mBackGroundColor); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int round = (int) (mCurrentBgHeight / 2); RectF rectBlackBg = new RectF(0, 0, mCurrentBgWidth, mCurrentBgHeight); canvas.drawRoundRect(rectBlackBg, round, round, mBgPaint); float section = currentCount / maxCount; RectF rectProgressBg = new RectF(0, 0, mWidth * section, mCurrentBgHeight); 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(0, 0, mWidth * section, mCurrentBgHeight, 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 */ private void setCurrentCount(float currentCount) { synchronized (mLock) { this.currentCount = currentCount > targetCount ? targetCount : currentCount; invalidate(); } } /*** * 設定當前的進度值 * * @param currentCount */ private void setCurrentBgWidth(float currentCount) { synchronized (mLock) { this.mCurrentBgWidth = currentCount > mWidth ? mWidth : currentCount; invalidate(); } } /*** * 設定當前的進度值 * * @param currentCount */ private void setCurrentBgHeight(float currentCount) { synchronized (mLock) { this.mCurrentBgHeight = currentCount > mHeight ? mHeight : currentCount; invalidate(); } } public float getTargetCount() { return targetCount; } public float getMaxCount() { return maxCount; } public float getCurrentCount() { return currentCount; } public void setTargetCount(float targetCount) { if (targetCount != 0 && targetCount < 10) targetCount = 10;//為了顯示效果 this.targetCount = targetCount > maxCount ? maxCount : targetCount; reset(); ValueAnimator animator = ValueAnimator.ofFloat(currentCount, targetCount); animator.setInterpolator(new AccelerateDecelerateInterpolator()); DURATION = (long) (targetCount * speed); animator.setDuration(DURATION); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { currentCount = (float) animation.getAnimatedValue(); mHandler.sendEmptyMessageDelayed(1, 100); } }); animator.start(); if (mHeight != 0) { startBgAnim(); } else needShowBgAnimDelay = true; } private void startBgAnim() { needShowBgAnimDelay = false; ValueAnimator animatorWidth = ValueAnimator.ofFloat(mCurrentBgWidth, mWidth); animatorWidth.setInterpolator(new AccelerateDecelerateInterpolator()); animatorWidth.setDuration((long) ((mWidth) * bgSpeed)); animatorWidth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mCurrentBgWidth = (float) animation.getAnimatedValue(); mHandler.sendEmptyMessageDelayed(2, 100); } }); animatorWidth.start(); ValueAnimator animatorHeight = ValueAnimator.ofFloat(mCurrentBgHeight, mHeight); animatorHeight.setInterpolator(new AccelerateDecelerateInterpolator()); animatorHeight.setDuration((long) ((mWidth) * bgSpeed)); animatorHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mCurrentBgHeight = (float) animation.getAnimatedValue(); mHandler.sendEmptyMessageDelayed(3, 100); } }); animatorHeight.start(); } private void reset() { currentCount = 0; mCurrentBgWidth = 0; mCurrentBgHeight = 0; invalidate(); } @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); if (needShowBgAnimDelay) startBgAnim(); } private Handler mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: setCurrentCount(currentCount); break; case 2: setCurrentBgWidth(mCurrentBgWidth); break; case 3: setCurrentBgHeight(mCurrentBgHeight); break; } } }; }

相關推薦

Android定義變色ProgressBar

效果圖 廢話不多說,直接上一張 gif圖有點暗,可能是截圖軟體的原因,來個靜態的效果,裡面是有個背景的噢 簡單介紹 一個圓角的漸變色progress的效果,載入時能從0增長到targetCount(如果需要改變顏色,直接在 privat

Android定義控制元件_變色圓形progressbar

產品跟圓槓上了系列,比較簡單的控制元件,記錄下方便下次直接取。主要用到sahder,神奇的漸變色 /**shader繪製漸變色的弧度*/ LinearGradient shader = new LinearGradient(0, mHei

Android定義文字閃爍變色的跑馬燈

最近因為專案需要,一直都在尋找比較貼合專案主題的跑馬燈,但是寫的demo都是可以執行的,但是整合到專案中的時候就不起作用了,看了許多的資料,最後總結這都是執行緒的問題,後來各種搗騰,終於寫出了一個比較合適的跑馬燈,整合到專案中也是可以執行的,希望大神能多多指點 自定義一個控

Android 定義圓形帶刻度變色的進度條

效果圖 一、繪製圓環 圓環故名思意,第一個首先繪製是圓環 1:圓環繪製函式 圓環API public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter,

android定義ProgressBar 修改進度條樣式 出現setProgress無效問題

在很多時候android系統提供的進度條樣式是不足以滿足我們的需求的,因此在大多數的時候,我們為了美觀,亦或者為了實現自己的功能,需要在系統的基礎上進行修改其樣式,當然你也可以自己從頭寫一個,不過個人覺得還是比較麻煩,好吧,廢話不多說了,進入正題。 昨天在做一個下載功能時,

Android 各種定義進度條Progressbar

Android 自定義進度條 Progressbar 控制元件集合 Seekbar with labelled intervals Like Olx FilterView Seekbar Android-ProgressViews

android定義ProgressBar(仿淘寶)的載入效果

三種方式實現自定義圓形頁面載入中效果的進度條 To get a ProgressBar in the default theme that is to be used on white/light back ground, use one of the inverse st

android定義view實現字型變色

上次看了鴻洋的部落格,其中有一篇部落格實現的是字型逐漸變色的效果,不過其使用的是clipRect實現的,今天給大家帶來另一種實現方式,通過XferMode來實現。先看效果吧。 先說下實現原理:我們首先繪製當前顯示的文字內容,然後設定xfermode的值為P

android 定義ProgressBar 文字跟隨進度效果

1 字型適配 private void textSizeAdaptive() { //1.獲取當前裝置的螢幕大小 DisplayMetrics display

android 定義橫向progressbar樣式

主要簡單編輯下資原始檔即可 <!--檔名(progressbar_bg)--> <?xml version="1.0" encoding="UTF-8"?> <lay

Android 定義View--ProgressBar篇(一)

1、概述 1.1 目的 : 在我們的日常開發中,有很多Android UI介面上有一些特殊或者特別的控制元件與介面,是Android自帶的控制元件所不能滿足的,需要我們自己定製一些適合的控制元件來完成。 1.2 Android自定義View步驟 : 自定

android定義轉圈progressbar

因為自帶的progressbar長得太醜了 美工那個醜男不知道從哪偷的帶箭頭的圓圈圖片,讓我自定義ProgressBar。那個醜男簡直人醜事多,真踏嗎s b一個。 簡單講自定義progressbar 總共分三步。 首先在drawable寫個轉圈的xml。  like thi

Android 定義控件之繼承ViewGroup創建新容器

多個 osi count() arc ron min ole tro 定位 歡迎大家來學習本節內容,前幾節我們已經學習了其他幾種自定義控件,分別是Andriod 自定義控件之音頻條及 Andriod 自定義控件之創建可以復用的組合控件還沒有學習的同學請先去學習下,因為本節將

Android定義相機超詳細講解

了解 catch 實現 4.4 required form 需要 eset 自己 Android自定義相機超詳細講解 轉載請標明出處: http://blog.csdn.net/vinicolor/article/details/49642861; 由於網上關於Andr

Android 定義View

wid declare created odi lex getwidth 實現 tdi led   最近在看鴻洋大神的博客,在看到自定義部分View部分時,想到之前案子中經常會要用到"圖片 + 文字"這類控件,如下圖所示: 之前的做法是在布局文件中,將一個Imag

Android 定義控件之 日期選擇控件

gin pri 選中 att files ger bottom null count() 效果如下: 調用的代碼: @OnClick(R.id.btn0) public void btn0() { final AlertDialog dialog

android 定義控件之簡單的loading框

void stroke color mat pri htm img 溫習 時機   好吧,久不動android,感覺自己已經快是條鹹魚了,趁著這周的開發任務已完成,下周的開發計劃未下來之際,來溫習一下android的自定義控件,於是就有了下面這個醜陋的玩意      實現起

aNDROID定義進度條顏色

定義 hao123 自定義進度條 com list andro 顏色 androi baidu DIaLOGFRaGMENT%E9%97%AE%E9%A2%98%E6%B1%82%E8%A7%A3 http://music.baidu.com/songlist/49564

aNDROID定義長點擊事件

list android aid 點擊事件 .com baidu andro oid lis %E6%8E%A8%E8%8D%90%E6%9A%82%E6%97%B6%E4%B8%8D%E8%A6%81%E5%8D%87%E7%BA%A7aDT22 http://musi

Android定義view詳解

this boolean mar 處理 都是 並且 jdk text 命名 從繼承開始 懂點面向對象語言知識的都知道:封裝,繼承和多態,這是面向對象的三個基本特征,所以在自定義View的時候,最簡單的方法就是繼承現有的View 通過上面這段代碼,我定義了一個Ske