Android自定義漸變色ProgressBar
效果圖
廢話不多說,直接上一張
gif圖有點暗,可能是截圖軟體的原因,來個靜態的效果,裡面是有個背景的噢
簡單介紹
一個圓角的漸變色progress的效果,載入時能從0增長到targetCount(如果需要改變顏色,直接在
private static final int[] SECTION_COLORS = {Color.parseColor("#FF62EBEE"), Color.parseColor("#FF50E2FB"), Color.parseColor("#FF4CE1FD")};
這裡改下就ok了,自定義你懂得,自己改改就好了)
如何用這個效果
- 在xml中使用該自定義控制元件
- 設定最大值
setMaxCount(float maxCount)
- 設定當前顯示值
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