欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Android自定義控件實(shí)現(xiàn)圓形進(jìn)度CircleProgressBar的方法

這篇文章主要講解了Android自定義控件實(shí)現(xiàn)圓形進(jìn)度CircleProgressBar的方法,內(nèi)容清晰明了,對(duì)此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會(huì)有幫助。

在江川等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需制作網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,成都營(yíng)銷網(wǎng)站建設(shè),外貿(mào)營(yíng)銷網(wǎng)站建設(shè),江川網(wǎng)站建設(shè)費(fèi)用合理。

近日有朋友問(wèn)我有沒(méi)有如下圖效果的開源控件

Android自定義控件實(shí)現(xiàn)圓形進(jìn)度CircleProgressBar的方法

相信大家無(wú)論是用IOS還是Android,都對(duì)這種效果不陌生,很多主流APP都會(huì)有這樣或類似的效果,之前也打算研究一下這類控件的代碼,苦于一直不知道應(yīng)該怎么搜索這種效果(就是關(guān)鍵詞)或者所搜的結(jié)果不是自己想要的,所以就一直擱置了下來(lái)。

正好朋友需要這種效果,所以就忙里偷閑寫了一個(gè)類似的、更加常見(jiàn)和適用范圍更多的控件,效果如下圖所示:

Android自定義控件實(shí)現(xiàn)圓形進(jìn)度CircleProgressBar的方法

自定義上圖所示效果的控件時(shí),其實(shí)就是用Canvas繪制不同效果,比如漸變圓弧背景、圓周白色分割線、中間文字等,這篇博客也根據(jù)繪制的順序依次闡述。

1.自定義CircleProgressBar,繼承View,并實(shí)現(xiàn)響應(yīng)的構(gòu)造函數(shù)

代碼如下:

/**
 * Created by WangChunLei on 2016.1.16
 * E-mail:wcl_android@163.com
 */
public class GradientProgressBar extends View {
 public GradientProgressBar(Context context) {
 super(context);
 init();
 }

 public GradientProgressBar(Context context, AttributeSet attrs) {
 super(context, attrs);
 init();
 }

 public GradientProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 init();
 }
}

其中init方法是對(duì)相關(guān)畫筆進(jìn)行初始化的方法,init方法代碼如下:

private void init() {
 backCirclePaint = new Paint();
 backCirclePaint.setStyle(Paint.Style.STROKE);
 backCirclePaint.setAntiAlias(true);
 backCirclePaint.setColor(Color.LTGRAY);
 backCirclePaint.setStrokeWidth(circleBorderWidth);
// backCirclePaint.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.OUTER));

 gradientCirclePaint = new Paint();
 gradientCirclePaint.setStyle(Paint.Style.STROKE);
 gradientCirclePaint.setAntiAlias(true);
 gradientCirclePaint.setColor(Color.LTGRAY);
 gradientCirclePaint.setStrokeWidth(circleBorderWidth);

 linePaint = new Paint();
 linePaint.setColor(Color.WHITE);
 linePaint.setStrokeWidth(5);

 textPaint = new Paint();
 textPaint.setAntiAlias(true);
 textPaint.setTextSize(textSize);
 textPaint.setColor(Color.BLACK);
 }

2.測(cè)量控件的寬高-onMeasure

onMeasure是自定義控件的第一步,目的就是測(cè)量得到該控件應(yīng)該占有的寬高尺寸。其中onMeasure方法的代碼如下:

@Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
 int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
 setMeasuredDimension(Math.min(measureWidth, measureHeight), Math.min(measureWidth, measureHeight));
 }

貼上onMeasure的代碼后,大家估計(jì)是很少見(jiàn)過(guò)測(cè)量過(guò)程這么簡(jiǎn)單的onMeasure,不要介意,有興趣的同僚們可以細(xì)化一下這個(gè)測(cè)量過(guò)程,對(duì)不同的測(cè)量模式分別進(jìn)行處理和測(cè)量,讓控件適配效果更好更完善!

onMeasure方法中,分別獲取期望的寬度和高度,并取其中較小的尺寸作為該控件的寬和高。

3.依次繪制不同的控件組成部分。

因?yàn)榭丶侵苯永^承自View,所以不需要再處理onLayout方法,這也是自定義View的難度遠(yuǎn)小于自定義ViewGroup的原因,但繼承ViewGroup也并不一定要重寫onMeasure。
要實(shí)現(xiàn)如圖所示的效果,需要分以下步驟依次實(shí)現(xiàn)

(1)繪制灰色空心圓環(huán)
(2)繪制顏色漸變的圓環(huán)
(3)繪制圓環(huán)上分割的白色線條
(4)繪制百分比文字等。

繪制過(guò)程過(guò),后繪制的內(nèi)容如果與之前繪制的內(nèi)容存在交集,則后繪制的內(nèi)容會(huì)覆蓋掉之前繪制的內(nèi)容。

按照上述步驟依次介紹

在繪制過(guò)程中,會(huì)產(chǎn)生以下成員變量,下文中會(huì)用到:

/*圓弧線寬*/
 private float circleBorderWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
 /*內(nèi)邊距*/
 private float circlePadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
 /*字體大小*/
 private float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 50, getResources().getDisplayMetrics());
 /*繪制圓周的畫筆*/
 private Paint backCirclePaint;
 /*繪制圓周白色分割線的畫筆*/
 private Paint linePaint;
 /*繪制文字的畫筆*/
 private Paint textPaint;
 /*百分比*/
 private int percent = 0;
 /*漸變圓周顏色數(shù)組*/
 private int[] gradientColorArray = new int[]{Color.GREEN, Color.parseColor("#fe751a"), Color.parseColor("#13be23"), Color.GREEN};
 private Paint gradientCirclePaint;

3.1繪制灰色空心圓環(huán)

代碼如下:

//1.繪制灰色背景圓環(huán)
 canvas.drawArc(
 new RectF(circlePadding * 2, circlePadding * 2,
  getMeasuredWidth() - circlePadding * 2, getMeasuredHeight() - circlePadding * 2), -90, 360, false, backCirclePaint);

其中,-90為繪制圓弧的起始角度,360是圓弧繪制的角度,即sweepAngle.

3.2繪制顏色漸變的圓環(huán)

//2.繪制顏色漸變圓環(huán)
 LinearGradient linearGradient = new LinearGradient(circlePadding, circlePadding,
 getMeasuredWidth() - circlePadding,
 getMeasuredHeight() - circlePadding,
 gradientColorArray, null, Shader.TileMode.MIRROR);
 gradientCirclePaint.setShader(linearGradient);
 gradientCirclePaint.setShadowLayer(10, 10, 10, Color.RED);
 canvas.drawArc(
 new RectF(circlePadding * 2, circlePadding * 2,
  getMeasuredWidth() - circlePadding * 2, getMeasuredHeight() - circlePadding * 2), -90, (float) (percent / 100.0) * 360, false, gradientCirclePaint);

其中,linearGradient是Paint的shadow,是為了圓弧的顏色漸變效果的而需要設(shè)置的,日常開發(fā)中應(yīng)用頻率不高,但的確是可以實(shí)現(xiàn)非常理想的顏色漸變效果。

3.3繪制圓環(huán)上分割的白色線條

繪制圓弧上的白色線條時(shí),需要進(jìn)行一些簡(jiǎn)單的運(yùn)算,比如線條的起始坐標(biāo)startX,startY和線條的終止坐標(biāo)stopX,stopY等,利用簡(jiǎn)單的三角函數(shù)還是很容易去計(jì)算出來(lái)的。
效果中,將圓弧使用白色線條平分成100分,每一個(gè)的階級(jí)為1,可以滿足int類型的百分比與效果圖比例的一致。

//半徑
float radius = (getMeasuredWidth() - circlePadding * 3) / 2;
 //X軸中點(diǎn)坐標(biāo)
 int centerX = getMeasuredWidth() / 2;

 //3.繪制100份線段,切分空心圓弧
 for (float i = 0; i < 360; i += 3.6) {
 double rad = i * Math.PI / 180;
 float startX = (float) (centerX + (radius - circleBorderWidth) * Math.sin(rad));
 float startY = (float) (centerX + (radius - circleBorderWidth) * Math.cos(rad));

 float stopX = (float) (centerX + radius * Math.sin(rad) + 1);
 float stopY = (float) (centerX + radius * Math.cos(rad) + 1);

 canvas.drawLine(startX, startY, stopX, stopY, linePaint);
 }

3.4繪制百分比文字等

最后繪制百分比文字。
繪制文字時(shí),為了保持文字的中心點(diǎn)和圓弧的原點(diǎn)一致,需要先測(cè)量得到要顯示文字的寬度和高度,然后再進(jìn)行一些簡(jiǎn)單的運(yùn)算,原理不再贅述,相信大家數(shù)學(xué)一定都比我好。

//4.繪制文字
float textWidth = textPaint.measureText(percent + "%");
int textHeight = (int) (Math.ceil(textPaint.getFontMetrics().descent - textPaint.getFontMetrics().ascent) + 2);
 canvas.drawText(percent + "%", centerX - textWidth / 2, centerX + textHeight / 4, textPaint);

最后,暴漏一個(gè)公共的方法供改變顯示的百分比,代碼如下:

/**
 * 設(shè)置百分比
 *
 * @param percent
 */
 public void setPercent(int percent) {
 if (percent < 0) {
 percent = 0;
 } else if (percent > 100) {
 percent = 100;
 }

 this.percent = percent;
 invalidate();
 }

至此,所有繪制過(guò)程簡(jiǎn)述完畢,130行代碼就能實(shí)現(xiàn)很炫酷的效果有木有?

最后,貼上項(xiàng)目完整代碼,供懶得看實(shí)現(xiàn)過(guò)程的同僚們使用,O(∩_∩)O哈哈~

package com.example.myview;

import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;

/**
 * Created by WangChunLei on 2016.1.16
 * e-mail:wcl_android@163.com
 */
public class GradientProgressBar extends View {
 /*圓弧線寬*/
 private float circleBorderWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
 /*內(nèi)邊距*/
 private float circlePadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics());
 /*字體大小*/
 private float textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 50, getResources().getDisplayMetrics());
 /*繪制圓周的畫筆*/
 private Paint backCirclePaint;
 /*繪制圓周白色分割線的畫筆*/
 private Paint linePaint;
 /*繪制文字的畫筆*/
 private Paint textPaint;
 /*百分比*/
 private int percent = 0;
 /*漸變圓周顏色數(shù)組*/
 private int[] gradientColorArray = new int[]{Color.GREEN, Color.parseColor("#fe751a"), Color.parseColor("#13be23"), Color.GREEN};
 private Paint gradientCirclePaint;

 public GradientProgressBar(Context context) {
 super(context);
 init();
 }

 public GradientProgressBar(Context context, AttributeSet attrs) {
 super(context, attrs);
 init();
 }

 public GradientProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 init();
 }

 private void init() {
 backCirclePaint = new Paint();
 backCirclePaint.setStyle(Paint.Style.STROKE);
 backCirclePaint.setAntiAlias(true);
 backCirclePaint.setColor(Color.LTGRAY);
 backCirclePaint.setStrokeWidth(circleBorderWidth);
// backCirclePaint.setMaskFilter(new BlurMaskFilter(20, BlurMaskFilter.Blur.OUTER));

 gradientCirclePaint = new Paint();
 gradientCirclePaint.setStyle(Paint.Style.STROKE);
 gradientCirclePaint.setAntiAlias(true);
 gradientCirclePaint.setColor(Color.LTGRAY);
 gradientCirclePaint.setStrokeWidth(circleBorderWidth);

 linePaint = new Paint();
 linePaint.setColor(Color.WHITE);
 linePaint.setStrokeWidth(5);

 textPaint = new Paint();
 textPaint.setAntiAlias(true);
 textPaint.setTextSize(textSize);
 textPaint.setColor(Color.BLACK);
 }


 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
 int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
 setMeasuredDimension(Math.min(measureWidth, measureHeight), Math.min(measureWidth, measureHeight));
 }

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 //1.繪制灰色背景圓環(huán)
 canvas.drawArc(
 new RectF(circlePadding * 2, circlePadding * 2,
  getMeasuredWidth() - circlePadding * 2, getMeasuredHeight() - circlePadding * 2), -90, 360, false, backCirclePaint);
 //2.繪制顏色漸變圓環(huán)
 LinearGradient linearGradient = new LinearGradient(circlePadding, circlePadding,
 getMeasuredWidth() - circlePadding,
 getMeasuredHeight() - circlePadding,
 gradientColorArray, null, Shader.TileMode.MIRROR);
 gradientCirclePaint.setShader(linearGradient);
 gradientCirclePaint.setShadowLayer(10, 10, 10, Color.RED);
 canvas.drawArc(
 new RectF(circlePadding * 2, circlePadding * 2,
  getMeasuredWidth() - circlePadding * 2, getMeasuredHeight() - circlePadding * 2), -90, (float) (percent / 100.0) * 360, false, gradientCirclePaint);

 //半徑
 float radius = (getMeasuredWidth() - circlePadding * 3) / 2;
 //X軸中點(diǎn)坐標(biāo)
 int centerX = getMeasuredWidth() / 2;

 //3.繪制100份線段,切分空心圓弧
 for (float i = 0; i < 360; i += 3.6) {
 double rad = i * Math.PI / 180;
 float startX = (float) (centerX + (radius - circleBorderWidth) * Math.sin(rad));
 float startY = (float) (centerX + (radius - circleBorderWidth) * Math.cos(rad));

 float stopX = (float) (centerX + radius * Math.sin(rad) + 1);
 float stopY = (float) (centerX + radius * Math.cos(rad) + 1);

 canvas.drawLine(startX, startY, stopX, stopY, linePaint);
 }

 //4.繪制文字
 float textWidth = textPaint.measureText(percent + "%");
 int textHeight = (int) (Math.ceil(textPaint.getFontMetrics().descent - textPaint.getFontMetrics().ascent) + 2);
 canvas.drawText(percent + "%", centerX - textWidth / 2, centerX + textHeight / 4, textPaint);
 }

 /**
 * 設(shè)置百分比
 *
 * @param percent
 */
 public void setPercent(int percent) {
 if (percent < 0) {
 percent = 0;
 } else if (percent > 100) {
 percent = 100;
 }

 this.percent = percent;
 invalidate();
 }
}

最后,貼上自定義控件代碼(自定義控件、Activity,布局文件)下載地址: Android圓形進(jìn)度CircleProgressBar

看完上述內(nèi)容,是不是對(duì)Android自定義控件實(shí)現(xiàn)圓形進(jìn)度CircleProgressBar的方法有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

文章題目:Android自定義控件實(shí)現(xiàn)圓形進(jìn)度CircleProgressBar的方法
分享URL:http://chinadenli.net/article20/ppchjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司標(biāo)簽優(yōu)化、定制開發(fā)、關(guān)鍵詞優(yōu)化、定制網(wǎng)站、虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
日本欧美一区二区三区就| 精品日韩视频在线观看| 欧美不卡高清一区二区三区| 精品国模一区二区三区欧美| 99秋霞在线观看视频| 日韩日韩日韩日韩在线| 欧美日韩国产黑人一区| 91欧美视频在线观看免费 | 国产高清一区二区白浆| 婷婷色网视频在线播放| 欧美一级黄片免费视频| 国产日本欧美特黄在线观看| 黄色片一区二区三区高清| 日本亚洲精品在线观看| 亚洲国产综合久久天堂| 欧洲日本亚洲一区二区| 欧美中文日韩一区久久| 好吊日在线观看免费视频| 中日韩免费一区二区三区| 日本不卡一区视频欧美| 中文字幕亚洲视频一区二区| 香蕉久久夜色精品国产尤物| 久久99午夜福利视频| av在线免费观看一区二区三区| 内射精品欧美一区二区三区久久久| 男女一进一出午夜视频| 日本加勒比在线观看不卡| 熟妇人妻av中文字幕老熟妇| 日韩在线一区中文字幕| 色无极东京热男人的天堂| 欧美亚洲三级视频在线观看| 国产精品自拍杆香蕉视频| 真实偷拍一区二区免费视频| 欧美国产日韩在线综合| 国产亚洲欧美一区二区| 国产在线小视频你懂的| 欧美日本亚欧在线观看| 日本亚洲欧美男人的天堂| 伊人色综合久久伊人婷婷| 激情五月天免费在线观看| 91人人妻人人爽人人狠狠|