Android自定義View繪制彩色圓弧
更新時(shí)間:2020年02月18日 08:03:57 作者:小燕子love
這篇文章主要為大家詳細(xì)介紹了Android自定義View繪制彩色圓弧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
本文實(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;//畫(huà)筆
private Paint paintFull;//實(shí)心圓畫(huà)筆
private Paint textPaint;//標(biāo)識(shí)字畫(huà)筆
private Paint valuePaint;//移動(dòng)小球畫(huà)筆
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è)置畫(huà)筆為無(wú)鋸齒
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è)置畫(huà)筆為無(wú)鋸齒
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è)置畫(huà)筆為無(wú)鋸齒
}
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;
//畫(huà)周?chē)∏蚝蛿?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);
//畫(huà)標(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) {//此處有問(wèn)題
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();
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android自定義環(huán)形LoadingView效果
這篇文章主要為大家詳細(xì)介紹了Android自定義環(huán)形LoadingView效果的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Kotlin1.6.20新功能Context?Receivers使用技巧揭秘
這篇文章主要為大家介紹了Kotlin1.6.20功能Context?Receivers使用揭秘,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
Android App開(kāi)發(fā)中自定義View和ViewGroup的實(shí)例教程
這篇文章主要介紹了Android App開(kāi)發(fā)中自定義View和ViewGroup的實(shí)例教程,分別介紹了進(jìn)度條和圖片上傳并排列的例子,效果很好很強(qiáng)大,需要的朋友可以參考下2016-05-05
詳解Android中常見(jiàn)的內(nèi)存優(yōu)化及內(nèi)存泄露場(chǎng)景
本文主要給大家介紹了Android中常見(jiàn)的內(nèi)存優(yōu)化及Android開(kāi)發(fā)中容易造成內(nèi)存泄露的場(chǎng)景,對(duì)我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-08-08

