日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

android自定义进度条样式,Android 自定义进度条

發(fā)布時(shí)間:2023/12/29 Android 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android自定义进度条样式,Android 自定义进度条 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

效果

國(guó)際慣例,效果圖奉上

在這里插入圖片描述

目錄

在這里插入圖片描述

前言

寫在前面,由于之前其實(shí)已經(jīng)寫了部分自定義View的方法,所以本來(lái)應(yīng)該按照之前的系列,來(lái)進(jìn)行下載暫停動(dòng)畫進(jìn)度條,但是我把之前的圓形進(jìn)度條和開始暫停動(dòng)畫效果合并后,出現(xiàn)了一點(diǎn)小問題,讓我發(fā)現(xiàn)之前寫的自定義View,沒有使我真正的了解自定義View,那么我覺得還是有很大的問題;那么之后依舊會(huì)努力的寫自定義View,初步先寫靜態(tài)的自定義View,之后,加上動(dòng)畫的自定義VIew,后續(xù)在加上相應(yīng)的觸摸事件,努力的把自定義VIew的方法方式全部給記錄下來(lái);努力的融匯貫通。

正文

HorizontalProgressBarWithNumber

橫向的進(jìn)度條;里面有詳細(xì)的注釋

首先繼承自ProgressBar,這個(gè)是對(duì)基礎(chǔ)的ProgressBar 進(jìn)行進(jìn)一步的自定義,

public class HorizontalProgressBarWithNumber extends ProgressBar{

******

}

當(dāng)我們想要自定義VIew的時(shí)候,先要構(gòu)思效果,那么就要設(shè)置各種屬性,如下

/**

* 設(shè)置各種默認(rèn)值

*/

private static final int DEFAULT_TEXT_SIZE = 10;

private static final int DEFAULT_TEXT_COLOR = 0XFFFC00D1;

private static final int DEFAULT_COLOR_UNREACHED_COLOR = 0xFFd3d6da;

private static final int DEFAULT_HEIGHT_REACHED_PROGRESS_BAR = 2;

private static final int DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR = 2;

private static final int DEFAULT_SIZE_TEXT_OFFSET = 10;

/**

* painter of all drawing things 所有畫圖所用的畫筆

*/

protected Paint mPaint = new Paint();

/**

* color of progress number 進(jìn)度號(hào)碼的顏色

*/

protected int mTextColor = DEFAULT_TEXT_COLOR;

/**

* size of text (sp) 文本的大小

*/

protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE);

/**

* offset of draw progress 進(jìn)度條文本補(bǔ)償寬度

*/

protected int mTextOffset = dp2px(DEFAULT_SIZE_TEXT_OFFSET);

/**

* height of reached progress bar 進(jìn)度條高度

*/

protected int mReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_REACHED_PROGRESS_BAR);

/**

* color of reached bar 成功的文本顏色

*/

protected int mReachedBarColor = DEFAULT_TEXT_COLOR;

/**

* color of unreached bar 未完成的bar顏色

*/

protected int mUnReachedBarColor = DEFAULT_COLOR_UNREACHED_COLOR;

/**

* height of unreached progress bar 未覆蓋的進(jìn)度條高度

*/

protected int mUnReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR);

/**

* view width except padding 除padding外的視圖寬度

*/

protected int mRealWidth;

protected boolean mIfDrawText = true;

protected static final int VISIBLE = 0;

自定義構(gòu)造函數(shù)

public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs)

{

this(context, attrs, 0);

}

public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs,

int defStyle)

{

super(context, attrs, defStyle);

obtainStyledAttributes(attrs);//初始化參數(shù)

mPaint.setTextSize(mTextSize);//文本大小

mPaint.setColor(mTextColor);//文本顏色

}

接下來(lái)就是初始化的代碼:

/**

* get the styled attributes 獲取屬性的樣式

*

* @param attrs

*/

private void obtainStyledAttributes(AttributeSet attrs)

{

// init values from custom attributes

final TypedArray attributes = getContext().obtainStyledAttributes(

attrs, R.styleable.HorizontalProgressBarWithNumber);

mTextColor = attributes

.getColor(

R.styleable.HorizontalProgressBarWithNumber_progress_text_color,

DEFAULT_TEXT_COLOR);

mTextSize = (int) attributes.getDimension(

R.styleable.HorizontalProgressBarWithNumber_progress_text_size,

mTextSize);

mReachedBarColor = attributes

.getColor(

R.styleable.HorizontalProgressBarWithNumber_progress_reached_color,

mTextColor);

mUnReachedBarColor = attributes

.getColor(

R.styleable.HorizontalProgressBarWithNumber_progress_unreached_color,

DEFAULT_COLOR_UNREACHED_COLOR);

mReachedProgressBarHeight = (int) attributes

.getDimension(

R.styleable.HorizontalProgressBarWithNumber_progress_reached_bar_height,

mReachedProgressBarHeight);

mUnReachedProgressBarHeight = (int) attributes

.getDimension(

R.styleable.HorizontalProgressBarWithNumber_progress_unreached_bar_height,

mUnReachedProgressBarHeight);

mTextOffset = (int) attributes

.getDimension(

R.styleable.HorizontalProgressBarWithNumber_progress_text_offset,

mTextOffset);

int textVisible = attributes

.getInt(R.styleable.HorizontalProgressBarWithNumber_progress_text_visibility,

VISIBLE);

if (textVisible != VISIBLE)

{

mIfDrawText = false;

}

attributes.recycle();

}

上面當(dāng)中的參數(shù)和屬性都在attr.xml中聲明的,如下

接下來(lái),我們要重寫onMeasure方法,在其中獲取父控件傳遞過來(lái)的參數(shù)

protected synchronized void onMeasure(int widthMeasureSpec,

int heightMeasureSpec)

{

int width = MeasureSpec.getSize(widthMeasureSpec);

int height = measureHeight(heightMeasureSpec);//高度

setMeasuredDimension(width, height);//必須調(diào)用該方法來(lái)存儲(chǔ)View經(jīng)過測(cè)量的到的寬度和高度

mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();//真正的寬度值是減去左右padding

}

其中measureHeight() 方法是獲取視圖的高度,視圖的樣式中擁有進(jìn)度條和文本,要判斷文本的高度和進(jìn)度條的高度;

/**

* EXACTLY:父控件告訴我們子控件了一個(gè)確定的大小,你就按這個(gè)大小來(lái)布局。比如我們指定了確定的dp值和macth_parent的情況。

* AT_MOST:當(dāng)前控件不能超過一個(gè)固定的最大值,一般是wrap_content的情況。

* UNSPECIFIED:當(dāng)前控件沒有限制,要多大就有多大,這種情況很少出現(xiàn)。

* @param measureSpec

* @return 視圖的高度

*/

private int measureHeight(int measureSpec)

{

int result = 0;

int specMode = MeasureSpec.getMode(measureSpec);//父布局告訴我們控件的類型

int specSize = MeasureSpec.getSize(measureSpec);//父布局傳過來(lái)的視圖大小

if (specMode == MeasureSpec.EXACTLY)

{

result = specSize;

} else

{

/**

* mPaint.descent() 最高點(diǎn)的高度

* mPaint.ascent() 最低點(diǎn)的高度

*/

float textHeight = (mPaint.descent() - mPaint.ascent());// 設(shè)置文本的高度

/**

* Math.abs() 返回絕對(duì)值

* Math.max 返回最大值

* Math.min 返回最小值

*/

result = (int) (getPaddingTop() + getPaddingBottom() + Math.max(

Math.max(mReachedProgressBarHeight,

mUnReachedProgressBarHeight), Math.abs(textHeight)));

if (specMode == MeasureSpec.AT_MOST)

{

result = Math.min(result, specSize);

}

}

return result;

}

以上全部完成后,就可以開始o(jì)nDraw()方法了;

/**

* 開始畫

*/

@Override

protected synchronized void onDraw(Canvas canvas)

{

canvas.save();

/**

* 設(shè)置偏移后的坐標(biāo)原點(diǎn) 以原來(lái)為基礎(chǔ)上偏移后, 例如: (100,100), translate(1,1), 坐標(biāo)原點(diǎn)(101,101);

*/

canvas.translate(getPaddingLeft(), getHeight() / 2);

boolean noNeedBg = false;

float radio = getProgress() * 1.0f / getMax();//設(shè)置進(jìn)度

float progressPosX = (int) (mRealWidth * radio);//設(shè)置當(dāng)前進(jìn)度的寬度

String text = getProgress() + "%";//設(shè)置文本

// mPaint.getTextBounds(text, 0, text.length(), mTextBound);

float textWidth = mPaint.measureText(text);//返回文本的寬度

float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;//設(shè)置文本的高度

if (progressPosX + textWidth > mRealWidth)

{//當(dāng)文本和當(dāng)前進(jìn)度的寬度大于bar的寬度時(shí)

progressPosX = mRealWidth - textWidth;

noNeedBg = true;

}

// draw reached bar 畫出bar

float endX = progressPosX - mTextOffset / 2;//繪制已到達(dá)的進(jìn)度

if (endX > 0)

{//繪制已到達(dá)的進(jìn)度

mPaint.setColor(mReachedBarColor);

mPaint.setStrokeWidth(mReachedProgressBarHeight);

canvas.drawLine(0, 0, endX, 0, mPaint);

}

// draw progress bar

// measure text bound

if (mIfDrawText)

{//繪制文本

mPaint.setColor(mTextColor);

canvas.drawText(text, progressPosX, -textHeight, mPaint);

}

// draw unreached bar

if (!noNeedBg)

{//繪制未到達(dá)的進(jìn)度條

float start = progressPosX + mTextOffset / 2 + textWidth;

mPaint.setColor(mUnReachedBarColor);

mPaint.setStrokeWidth(mUnReachedProgressBarHeight);

canvas.drawLine(start, 0, mRealWidth, 0, mPaint);

}

canvas.restore();

}

在分享兩個(gè)轉(zhuǎn)換的方法

/**

* dp 2 px

*

* @param dpVal

*/

protected int dp2px(int dpVal)

{

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,

dpVal, getResources().getDisplayMetrics());

}

/**

* sp 2 px

*

* @param spVal

* @return

*/

protected int sp2px(int spVal)

{

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,

spVal, getResources().getDisplayMetrics());

}

最后自定義View 全部實(shí)現(xiàn),奉上全部代碼

public class HorizontalProgressBarWithNumber extends ProgressBar

{

/**

* 設(shè)置各種默認(rèn)值

*/

private static final int DEFAULT_TEXT_SIZE = 10;

private static final int DEFAULT_TEXT_COLOR = 0XFFFC00D1;

private static final int DEFAULT_COLOR_UNREACHED_COLOR = 0xFFd3d6da;

private static final int DEFAULT_HEIGHT_REACHED_PROGRESS_BAR = 2;

private static final int DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR = 2;

private static final int DEFAULT_SIZE_TEXT_OFFSET = 10;

/**

* painter of all drawing things 所有畫圖所用的畫筆

*/

protected Paint mPaint = new Paint();

/**

* color of progress number 進(jìn)度號(hào)碼的顏色

*/

protected int mTextColor = DEFAULT_TEXT_COLOR;

/**

* size of text (sp) 文本的大小

*/

protected int mTextSize = sp2px(DEFAULT_TEXT_SIZE);

/**

* offset of draw progress 進(jìn)度條文本補(bǔ)償寬度

*/

protected int mTextOffset = dp2px(DEFAULT_SIZE_TEXT_OFFSET);

/**

* height of reached progress bar 進(jìn)度條高度

*/

protected int mReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_REACHED_PROGRESS_BAR);

/**

* color of reached bar 成功的文本顏色

*/

protected int mReachedBarColor = DEFAULT_TEXT_COLOR;

/**

* color of unreached bar 未完成的bar顏色

*/

protected int mUnReachedBarColor = DEFAULT_COLOR_UNREACHED_COLOR;

/**

* height of unreached progress bar 未覆蓋的進(jìn)度條高度

*/

protected int mUnReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR);

/**

* view width except padding 除padding外的視圖寬度

*/

protected int mRealWidth;

protected boolean mIfDrawText = true;

protected static final int VISIBLE = 0;

public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs)

{

this(context, attrs, 0);

}

public HorizontalProgressBarWithNumber(Context context, AttributeSet attrs,

int defStyle)

{

super(context, attrs, defStyle);

obtainStyledAttributes(attrs);//初始化參數(shù)

mPaint.setTextSize(mTextSize);//文本大小

mPaint.setColor(mTextColor);//文本顏色

}

@Override

protected synchronized void onMeasure(int widthMeasureSpec,

int heightMeasureSpec)

{

int width = MeasureSpec.getSize(widthMeasureSpec);

int height = measureHeight(heightMeasureSpec);//高度

setMeasuredDimension(width, height);//必須調(diào)用該方法來(lái)存儲(chǔ)View經(jīng)過測(cè)量的到的寬度和高度

mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();//真正的寬度值是減去左右padding

}

/**

* EXACTLY:父控件告訴我們子控件了一個(gè)確定的大小,你就按這個(gè)大小來(lái)布局。比如我們指定了確定的dp值和macth_parent的情況。

* AT_MOST:當(dāng)前控件不能超過一個(gè)固定的最大值,一般是wrap_content的情況。

* UNSPECIFIED:當(dāng)前控件沒有限制,要多大就有多大,這種情況很少出現(xiàn)。

* @param measureSpec

* @return 視圖的高度

*/

private int measureHeight(int measureSpec)

{

int result = 0;

int specMode = MeasureSpec.getMode(measureSpec);//父布局告訴我們控件的類型

int specSize = MeasureSpec.getSize(measureSpec);//父布局傳過來(lái)的視圖大小

if (specMode == MeasureSpec.EXACTLY)

{

result = specSize;

} else

{

/**

* mPaint.descent() 最高點(diǎn)的高度

* mPaint.ascent() 最低點(diǎn)的高度

*/

float textHeight = (mPaint.descent() - mPaint.ascent());// 設(shè)置文本的高度

/**

* Math.abs() 返回絕對(duì)值

* Math.max 返回最大值

* Math.min 返回最小值

*/

result = (int) (getPaddingTop() + getPaddingBottom() + Math.max(

Math.max(mReachedProgressBarHeight,

mUnReachedProgressBarHeight), Math.abs(textHeight)));

if (specMode == MeasureSpec.AT_MOST)

{

result = Math.min(result, specSize);

}

}

return result;

}

/**

* get the styled attributes 獲取屬性的樣式

*

* @param attrs

*/

private void obtainStyledAttributes(AttributeSet attrs)

{

// init values from custom attributes

final TypedArray attributes = getContext().obtainStyledAttributes(

attrs, R.styleable.HorizontalProgressBarWithNumber);

mTextColor = attributes

.getColor(

R.styleable.HorizontalProgressBarWithNumber_progress_text_color,

DEFAULT_TEXT_COLOR);

mTextSize = (int) attributes.getDimension(

R.styleable.HorizontalProgressBarWithNumber_progress_text_size,

mTextSize);

mReachedBarColor = attributes

.getColor(

R.styleable.HorizontalProgressBarWithNumber_progress_reached_color,

mTextColor);

mUnReachedBarColor = attributes

.getColor(

R.styleable.HorizontalProgressBarWithNumber_progress_unreached_color,

DEFAULT_COLOR_UNREACHED_COLOR);

mReachedProgressBarHeight = (int) attributes

.getDimension(

R.styleable.HorizontalProgressBarWithNumber_progress_reached_bar_height,

mReachedProgressBarHeight);

mUnReachedProgressBarHeight = (int) attributes

.getDimension(

R.styleable.HorizontalProgressBarWithNumber_progress_unreached_bar_height,

mUnReachedProgressBarHeight);

mTextOffset = (int) attributes

.getDimension(

R.styleable.HorizontalProgressBarWithNumber_progress_text_offset,

mTextOffset);

int textVisible = attributes

.getInt(R.styleable.HorizontalProgressBarWithNumber_progress_text_visibility,

VISIBLE);

if (textVisible != VISIBLE)

{

mIfDrawText = false;

}

attributes.recycle();

}

/**

* 開始畫

*/

@Override

protected synchronized void onDraw(Canvas canvas)

{

canvas.save();

/**

* 設(shè)置偏移后的坐標(biāo)原點(diǎn) 以原來(lái)為基礎(chǔ)上偏移后, 例如: (100,100), translate(1,1), 坐標(biāo)原點(diǎn)(101,101);

*/

canvas.translate(getPaddingLeft(), getHeight() / 2);

boolean noNeedBg = false;

float radio = getProgress() * 1.0f / getMax();//設(shè)置進(jìn)度

float progressPosX = (int) (mRealWidth * radio);//設(shè)置當(dāng)前進(jìn)度的寬度

String text = getProgress() + "%";//設(shè)置文本

// mPaint.getTextBounds(text, 0, text.length(), mTextBound);

float textWidth = mPaint.measureText(text);//返回文本的寬度

float textHeight = (mPaint.descent() + mPaint.ascent()) / 2;//設(shè)置文本的高度

if (progressPosX + textWidth > mRealWidth)

{//當(dāng)文本和當(dāng)前進(jìn)度的寬度大于bar的寬度時(shí)

progressPosX = mRealWidth - textWidth;

noNeedBg = true;

}

// draw reached bar 畫出bar

float endX = progressPosX - mTextOffset / 2;//設(shè)置文本補(bǔ)償寬度

if (endX > 0)

{

mPaint.setColor(mReachedBarColor);

mPaint.setStrokeWidth(mReachedProgressBarHeight);

canvas.drawLine(0, 0, endX, 0, mPaint);

}

// draw progress bar

// measure text bound

if (mIfDrawText)

{

mPaint.setColor(mTextColor);

canvas.drawText(text, progressPosX, -textHeight, mPaint);

}

// draw unreached bar

if (!noNeedBg)

{

float start = progressPosX + mTextOffset / 2 + textWidth;

mPaint.setColor(mUnReachedBarColor);

mPaint.setStrokeWidth(mUnReachedProgressBarHeight);

canvas.drawLine(start, 0, mRealWidth, 0, mPaint);

}

canvas.restore();

}

/**

* dp 2 px

*

* @param dpVal

*/

protected int dp2px(int dpVal)

{

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,

dpVal, getResources().getDisplayMetrics());

}

/**

* sp 2 px

*

* @param spVal

* @return

*/

protected int sp2px(int spVal)

{

return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,

spVal, getResources().getDisplayMetrics());

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mRealWidth = w - getPaddingRight() - getPaddingLeft();

}

}

實(shí)現(xiàn)

xml界面

xmlns:tools="http://schemas.android.com/tools"

xmlns:zhy="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent" >

android:id="@+id/id_progressbar01"

android:layout_width="300dp"

android:layout_height="wrap_content"

android:layout_marginTop="50dip"

android:padding="5dp" />

mainActivity() 實(shí)現(xiàn)

public class MainActivity extends Activity {

private HorizontalProgressBarWithNumber mProgressBar;

private Handler mHandler = new Handler() {

public void handleMessage(android.os.Message msg) {

int progress = mProgressBar.getProgress();

mProgressBar.setProgress(++progress);

if (progress >= 100) {

mHandler.removeMessages(MSG_PROGRESS_UPDATE);

}

mHandler.sendEmptyMessageDelayed(MSG_PROGRESS_UPDATE, 100);

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mProgressBar = (HorizontalProgressBarWithNumber) findViewById(R.id.id_progressbar01);

mHandler.sendEmptyMessage(MSG_PROGRESS_UPDATE);

}

以上就是全部功能的實(shí)現(xiàn)了

總結(jié)

自定義View

先構(gòu)思效果

根據(jù)效果 , 聲明配置相應(yīng)參數(shù)

想好怎么計(jì)算View的寬度和高度

如果畫出來(lái)

開始做吧

感謝

這個(gè)是從鴻陽(yáng)大神的Github上找到的例子,嗯,值得學(xué)習(xí),感謝鴻陽(yáng)大神;

總結(jié)

以上是生活随笔為你收集整理的android自定义进度条样式,Android 自定义进度条的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。