Android自定義View繪制彩色圓弧
本文實(shí)例為大家分享了Android自定義View繪制彩色圓弧的具體代碼,供大家參考,具體內(nèi)容如下
效果如下:
自定義View代碼如下:
package com.example.yan; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.graphics.SweepGradient; import android.util.AttributeSet; import android.view.View; /** * Created by xiaoyanzi on 2016/3/18. * 漸變圓弧 */ public class GradualView extends View { private Context context; private Paint paint;//畫筆 private Paint paintFull;//實(shí)心圓畫筆 private Paint textPaint;//標(biāo)識(shí)字畫筆 private Paint valuePaint;//移動(dòng)小球畫筆 private int[] mColors;//漸變色數(shù)組 private int centerX;//中心X private int centerY;//中心Y private int srcH;//控件高度 private float startAngle = 110;//圓弧起始角度 private float sweepAngle = 320;//圓弧所占度數(shù) private float airValue = 66; /** * 直接在代碼中調(diào)用時(shí),使用該函數(shù) * * @param context */ public GradualView(Context context) { super(context); initData(context); } /** * 在xml中使用自定義view時(shí),使用這個(gè)函數(shù) * * @param context * @param attrs */ public GradualView(Context context, AttributeSet attrs) { super(context, attrs); initData(context); } /** * 可以由上一個(gè)函數(shù)中手動(dòng)調(diào)用 * * @param context * @param atrrs * @param defStyle 自定義函數(shù)中的attrs表示view的屬性集,defStyle表示默認(rèn)的屬性資源集的id */ public GradualView(Context context, AttributeSet atrrs, int defStyle) { super(context, atrrs, defStyle); } /** * 初始化 * @param context */ private void initData(Context context) { this.context = context; paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStyle(Paint.Style.STROKE); mColors = new int[]{ 0xFF660099,//紫色 0xFF330033,//褐色 0xFF99FF00,//草綠色 0xFFFFFF00,//黃色 0xFFFF6600,//橘色 0xFFFF0000,//紅色 0xFF660099,//紫色 }; Shader s = new SweepGradient(0, 0, mColors, null); paint.setAntiAlias(true);//設(shè)置畫筆為無鋸齒 paint.setStrokeWidth(dip2px(context, 14));//線寬 paint.setShader(s); paintFull = new Paint(Paint.ANTI_ALIAS_FLAG); paintFull.setStyle(Paint.Style.FILL_AND_STROKE); paintFull.setAntiAlias(true);//設(shè)置畫筆為無鋸齒 paintFull.setShader(s); textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); textPaint.setTextSize(dip2px(context, 22));//設(shè)置字體大小 textPaint.setColor(0xFFFFFFFF); valuePaint = new Paint(Paint.ANTI_ALIAS_FLAG); valuePaint.setAntiAlias(true);//設(shè)置畫筆為無鋸齒 } public void setAirValue(float airValue) { this.airValue = airValue; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); srcH = h; centerX = w / 2; centerY = h / 2; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float r = srcH / 2 - paint.getStrokeWidth() * 0.5f - dip2px(context, 200); //移動(dòng)中心 canvas.translate(centerX, centerY); RectF oval = new RectF(); oval.left = -r;//左邊 oval.top = -r;//上邊 oval.right = r;//右邊 oval.bottom = r;//下邊 canvas.drawArc(oval, startAngle, sweepAngle, false, paint); //繪制圓弧 //繪制圓弧兩頭的小圓 float mr = dip2px(context, 7); float x1 = (float) (-r * Math.sin((360 - sweepAngle) / 2 * Math.PI / 180)); float y1 = (float) (r * Math.cos((360 - sweepAngle) / 2 * Math.PI / 180)); canvas.drawCircle(x1, y1, mr, paintFull); float x2 = (float) (r * Math.sin((360 - sweepAngle) / 2 * Math.PI / 180)); float y2 = (float) (r * Math.cos((360 - sweepAngle) / 2 * Math.PI / 180)); canvas.drawCircle(x2, y2, mr, paintFull); //小圓離球的距離 float range = r + dip2px(context, 30); float ar = 12f; //畫周圍小球和數(shù)字 float ax1 = (float) (-range * Math.sin(45 * Math.PI / 180)); float ay1 = (float) (range * Math.cos(45 * Math.PI / 180)); canvas.drawCircle(ax1, ay1, ar, paintFull); canvas.drawText("0", ax1 - getTextW() * 3, ay1 + getTextH() / 2, textPaint); float ax2 = -range; float ay2 = 0; canvas.drawCircle(ax2, ay2, ar, paintFull); canvas.drawText("50", ax2 - getTextW() * 5, ay2 + getTextH() / 2, textPaint); float ax3 = (float) (-range * Math.sin(45 * Math.PI / 180)); float ay3 = (float) (-range * Math.cos(45 * Math.PI / 180)); canvas.drawCircle(ax3, ay3, ar, paintFull); canvas.drawText("100", ax3 - getTextW() * 7, ay3 + getTextH() / 2, textPaint); float ax4 = 0; float ay4 = -range; canvas.drawCircle(ax4, ay4, ar, paintFull); canvas.drawText("150", ax4 - getTextW() * 3, ay4 - getTextH(), textPaint); float ax5 = (float) (range * Math.sin(45 * Math.PI / 180)); float ay5 = (float) (-range * Math.cos(45 * Math.PI / 180)); canvas.drawCircle(ax5, ay5, ar, paintFull); canvas.drawText("200", ax5 + getTextW(), ay5 + getTextH() / 2, textPaint); float ax6 = range; float ay6 = 0; canvas.drawCircle(ax6, ay6, ar, paintFull); canvas.drawText("300", ax6 + getTextW(), ay6 + getTextH() / 2, textPaint); float ax7 = (float) (range * Math.sin(45 * Math.PI / 180)); float ay7 = (float) (range * Math.cos(45 * Math.PI / 180)); canvas.drawCircle(ax7, ay7, ar, paintFull); canvas.drawText("500", ax7 + getTextW(), ay7 + getTextH() / 2, textPaint); //畫標(biāo)識(shí)小球 valuePaint.setColor(0xFFFFFFFF); float cx; float cy; if (airValue >= 0 && airValue <= 50) { cx = (float) (-r * Math.cos((45 - airValue * 0.9) * Math.PI / 180)); cy = (float) (r * Math.sin((45 - airValue * 0.9) * Math.PI / 180)); } else if (airValue > 50 && airValue <= 150) { cx = (float) (-r * Math.cos((airValue * 0.9 - 45) * Math.PI / 180)); cy = (float) (-r * Math.sin((airValue * 0.9 - 45) * Math.PI / 180)); } else if (airValue > 150 && airValue <= 200) { cx = (float) (-r * Math.cos((airValue * 0.9 - 45) * Math.PI / 180)); cy = (float) (-r * Math.sin((airValue * 0.9 - 45) * Math.PI / 180)); } else if (airValue > 200 && airValue <= 300) { cx = (float) (-r * Math.cos((airValue * 0.45 + 45) * Math.PI / 180)); cy = (float) (-r * Math.sin((airValue * 0.45 + 45) * Math.PI / 180)); } else if (airValue > 300 && airValue <= 500) {//此處有問題 cx = (float) (r * Math.cos(((airValue - 300) * 0.225) * Math.PI / 180)); cy = (float) (r * Math.sin(((airValue - 300) * 0.225) * Math.PI / 180)); } else { cx = (float) (-r * Math.cos(45 * Math.PI / 180)); cy = (float) (r * Math.sin(45 * Math.PI / 180)); } canvas.drawCircle(cx, cy, dip2px(context, 11), valuePaint); canvas.drawCircle(cx, cy, dip2px(context, 4), paintFull); } /** * dip轉(zhuǎn)px * @param context * @param dpValue * @return */ private int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 獲取"正"的高度 * * @return */ private float getTextH() { Paint pFont = new Paint(); Rect rect = new Rect(); //返回包圍整個(gè)字符串的最小的一個(gè)Rect區(qū)域 pFont.getTextBounds("正", 0, 1, rect); return rect.height(); } /** * 獲取"正"的寬度 * * @return */ private float getTextW() { Paint pFont = new Paint(); Rect rect = new Rect(); //返回包圍整個(gè)字符串的最小的一個(gè)Rect區(qū)域 pFont.getTextBounds("正", 0, 1, rect); return rect.width(); } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android實(shí)現(xiàn)類似360,QQ管家那樣的懸浮窗
用到的就是WindowManager以及WindowManager.LayoutParams,對這個(gè)LayoutParams做文章,當(dāng)設(shè)置為屬性后,然后,創(chuàng)建一個(gè)View,將這個(gè)View添加到WindowManager中就行2013-06-06flutter日期選擇器 flutter時(shí)間選擇器
這篇文章主要為大家詳細(xì)介紹了flutter日期選擇器,flutter時(shí)間選擇器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07Android App中讀取XML與JSON格式數(shù)據(jù)的基本方法示例
這篇文章主要介紹了Android App中讀取XML與JSON格式數(shù)據(jù)的基本方法示例,Android中自帶的JSONObject非常好用,需要的朋友可以參考下2016-03-03Android?應(yīng)用程序的啟動(dòng)流程示例詳解
這篇文章主要為大家介紹了Android?應(yīng)用程序的啟動(dòng)流程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Android Fragment與Activity之間的相互通信實(shí)例代碼
這篇文章主要介紹了Android Fragment與Activity之間的相互通信的相關(guān)資料,并附簡單實(shí)例代碼,需要的朋友可以參考下2016-11-11Android、iOS和Windows Phone中的推送技術(shù)詳解
這篇文章主要介紹了Android、iOS和Windows Phone中的推送技術(shù)詳解,推送技術(shù)的實(shí)現(xiàn)通常會(huì)使用服務(wù)端向客戶端推送消息的方式,也就是說客戶端通過用戶名、Key等ID注冊到服務(wù)端后,在服務(wù)端就可以將消息向所有活動(dòng)的客戶端發(fā)送,需要的朋友可以參考下2015-01-01Flutter加載圖片流程之ImageProvider源碼示例解析
這篇文章主要為大家介紹了Flutter加載圖片流程之ImageProvider源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04