国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android自定義控件實(shí)現(xiàn)帶數(shù)值和動(dòng)畫(huà)的圓形進(jìn)度條

2019-10-21 21:31:48
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

本文實(shí)例實(shí)現(xiàn)一個(gè)如下圖所示的Android自定義控件,可以直觀地展示某個(gè)球隊(duì)在某個(gè)賽季的積分?jǐn)?shù)和勝場(chǎng)、負(fù)場(chǎng)、平局?jǐn)?shù)

Android,進(jìn)度條

首先對(duì)畫(huà)布進(jìn)行區(qū)域劃分,整個(gè)控件分上下兩部分

上邊是個(gè)大的圓環(huán),圓環(huán)中間兩行文字,沒(méi)什么難度,選好圓心坐標(biāo)和半徑后直接繪制即可,繪制文字也是如此。

下部分是三個(gè)小的圓弧進(jìn)度條,弧的末端繪制一個(gè)小的實(shí)心圓

首先選好坐標(biāo)和半徑,然后先繪制三個(gè)圓環(huán)作為弧形進(jìn)度條的背景

之后從12點(diǎn)鐘開(kāi)始繪制進(jìn)度弧,知道了圓環(huán)的圓心和半徑,也知道了弧對(duì)應(yīng)于12點(diǎn)鐘和圓環(huán)圓心的偏移角度

通過(guò)三角函數(shù)可以計(jì)算出進(jìn)度弧終點(diǎn)坐標(biāo),以進(jìn)度弧終點(diǎn)坐標(biāo)為圓心繪制一個(gè)小的實(shí)心圓即可

動(dòng)畫(huà)效果通過(guò)Handler的postDelayed方法觸發(fā)重繪即可實(shí)現(xiàn)

在項(xiàng)目中的效果如圖所示:

Android,進(jìn)度條

測(cè)試代碼如下:

final Random random=new Random();final ScoreBoardView myView=(ScoreBoardView)findViewById(R.id.custom_view);myView.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){  myView.setColor(Color.BLUE);  myView.setScore(random.nextInt(28));  myView.setWinDrawLose(random.nextInt(12),random.nextInt(15),random.nextInt(26)); }});

完整代碼如下:

public class ScoreBoardView extends View { private Context context; /*弧的顏色*/ private int mColor; /*積分?jǐn)?shù),勝場(chǎng)數(shù),平局?jǐn)?shù),負(fù)場(chǎng)數(shù)*/ private int mScore, mWinNumber, mDrawNumber, mLoseNumber; /*傳入數(shù)字的最大值*/ private final int FULL_SCORE = 30; /*動(dòng)畫(huà)插值器*/ DecelerateInterpolator mDecelerateInterpolator = new DecelerateInterpolator(); /*動(dòng)畫(huà)持續(xù)時(shí)間(刷新次數(shù))*/ private int mDuration = 10; /*動(dòng)畫(huà)刷新過(guò)程中的當(dāng)前值*/ private int mCurrentTime = 0; private TypedValue typedValue; private TypedValue typedValue1; private Handler mHandler = new Handler(); private Runnable mAnimation = new Runnable() {  @Override  public void run() {   if (mCurrentTime < mDuration) {    mCurrentTime++;    /*導(dǎo)致重繪調(diào)用onDraw,onDraw最后再次postDelay執(zhí)行此動(dòng)畫(huà),直到達(dá)到指定的次數(shù)*/    ScoreBoardView.this.invalidate();   }  } }; /*繪制圖形*/ private Paint paint = new Paint(); /*繪制文字*/ private Paint paintText = new Paint();  public ScoreBoardView(Context context) {  super(context);  this.context=context;  init(); }  public ScoreBoardView(Context context, AttributeSet attrs) {  super(context, attrs);  this.context=context;  init(); }  public ScoreBoardView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  this.context=context;  init(); }  private void init() {  /*數(shù)據(jù)初始化,默認(rèn)屬性*/  mColor = Color.rgb(95, 112, 72);  mScore = 0;  mWinNumber = 0;  mDrawNumber = 0;  mLoseNumber = 0;  typedValue=new TypedValue();  typedValue1=new TypedValue();  context.getTheme().resolveAttribute(R.attr.maintextclor, typedValue, true);  context.getTheme().resolveAttribute(R.attr.maintextclor_reverse,typedValue1,true); }  @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  /*獲取控件總的寬高*/  float totalWidth = getWidth();  float totalHeight = getHeight();  /*  * DecelerateInterpolator:動(dòng)畫(huà)從開(kāi)始到結(jié)束,變化率是一個(gè)減速的過(guò)程。  * AccelerateInterpolator:動(dòng)畫(huà)從開(kāi)始到結(jié)束,變化率是一個(gè)加速的過(guò)程。  * CycleInterpolator:動(dòng)畫(huà)從開(kāi)始到結(jié)束,變化率是循環(huán)給定次數(shù)的正弦曲線(xiàn)  * AccelerateDecelerateInterpolator:動(dòng)畫(huà)從開(kāi)始到結(jié)束,變化率是先加速后減速的過(guò)程。  * LinearInterpolator:動(dòng)畫(huà)從開(kāi)始到結(jié)束,變化率是線(xiàn)性變化。  * */  /*計(jì)算當(dāng)前時(shí)刻動(dòng)畫(huà)進(jìn)度值*/  float AnimCurrentValue =mDecelerateInterpolator.getInterpolation(1.0f * mCurrentTime / mDuration);   /*圖形畫(huà)筆設(shè)置*/  paint.setAntiAlias(true);  paint.setStyle(Paint.Style.STROKE);   /*積分?jǐn)?shù),上邊的大圓*/  paint.setStrokeWidth(4);  paint.setColor(mColor);  /*積分大圓的中心坐標(biāo)和半徑*/  float score_radius = totalHeight * 1 / 5, score_circle_x = totalWidth / 2, score_circle_y = totalHeight / 3;  /*繪制圓弧*/  canvas.drawCircle(score_circle_x, score_circle_y, score_radius, paint);  /*文字畫(huà)筆基本設(shè)置*/  paintText.setAntiAlias(true);  paintText.setStyle(Paint.Style.STROKE);  /*文字從中間開(kāi)始繪制*/  /*Paint.Align.CENTER:The text is drawn centered horizontally on the x,y origin*/  paintText.setTextAlign(Paint.Align.CENTER);  /*文字畫(huà)筆大小和顏色設(shè)置*/  paintText.setTextSize(score_radius * 3 / 4);  paintText.setColor(getResources().getColor(typedValue.resourceId));  /*圓心位置繪制積分?jǐn)?shù)值*/  canvas.drawText("" + mScore, score_circle_x, score_circle_y, paintText);  /*縮小字體繪制文本信息*/  paintText.setTextSize(score_radius * 1 / 4);  paintText.setAlpha(80);  /*圓心下邊繪制文本*/  canvas.drawText("積分", score_circle_x, score_circle_y + score_radius / 2, paintText);   /*設(shè)置畫(huà)筆,畫(huà)下邊的三個(gè)小圓*/  paint.setStrokeWidth(4);  paint.setAlpha(255);  /*下邊三個(gè)小圓的半徑*/  float small_radius = totalHeight / 10;  /*三個(gè)小圓的圓心的x坐標(biāo)*/  float[] circleXs = new float[]{totalWidth / 2 - score_radius * 3 / 2,          totalWidth / 2,          totalWidth / 2 + score_radius * 3 / 2};  /*三個(gè)小圓的圓心的y坐標(biāo)*/  float circleY = totalHeight * 3 / 4;  /*計(jì)算三個(gè)小圓弧掃過(guò)的角度*/  float[] theta_values = new float[]{360 * mWinNumber / FULL_SCORE* AnimCurrentValue,           360 * mDrawNumber / FULL_SCORE* AnimCurrentValue,           360 * mLoseNumber / FULL_SCORE* AnimCurrentValue};  /*設(shè)置畫(huà)筆顏色,繪制外圍圓環(huán)*/  paint.setColor(getResources().getColor(typedValue1.resourceId));  /*分別繪制三個(gè)外圍圓環(huán)*/  canvas.drawCircle(circleXs[0], circleY, small_radius, paint);//畫(huà)WIN背景圓  canvas.drawCircle(circleXs[1], circleY, small_radius, paint);//畫(huà)DRAW背景圓  canvas.drawCircle(circleXs[2], circleY, small_radius, paint);//畫(huà)LOSE背景圓  /*更改畫(huà)筆顏色,繪制圓弧進(jìn)度條*/  paint.setColor(mColor);  /*drawArc的起始角度是3點(diǎn)鐘方向,因此要從12點(diǎn)鐘方向開(kāi)始繪制,起始角度為270度*/  canvas.drawArc(new RectF(circleXs[0] - small_radius,         circleY - small_radius,         circleXs[0] + small_radius,         circleY + small_radius),      270, theta_values[0], false, paint);//畫(huà)WIN圓形進(jìn)度條  canvas.drawArc(new RectF(circleXs[1] - small_radius,         circleY - small_radius,         circleXs[1] + small_radius,         circleY + small_radius),      270, theta_values[1], false, paint);//畫(huà)DRAW圓形進(jìn)度條  canvas.drawArc(new RectF(circleXs[2] - small_radius,         circleY - small_radius,         circleXs[2] + small_radius,         circleY + small_radius),      270, theta_values[2], false, paint);//畫(huà)LOSE圓形進(jìn)度條  /*繪制圓弧結(jié)束處的小圓點(diǎn),實(shí)心圓*/  paint.setStyle(Paint.Style.FILL);  /*已知半徑、圓心位置、便宜角度,根據(jù)三角函數(shù)很方便計(jì)算出小實(shí)心圓圓心坐標(biāo)*/  canvas.drawCircle(circleXs[0] + small_radius * (float) Math.sin(theta_values[0] * Math.PI / 180),    circleY - small_radius * (float) Math.cos(theta_values[0] * Math.PI / 180), 6, paint);//畫(huà)WIN末尾小圓點(diǎn)  canvas.drawCircle(circleXs[1] + small_radius * (float) Math.sin(theta_values[1] * Math.PI / 180),    circleY - small_radius * (float) Math.cos(theta_values[1] * Math.PI / 180), 6, paint);//畫(huà)DRAW末尾小圓點(diǎn)  canvas.drawCircle(circleXs[2] + small_radius * (float) Math.sin(theta_values[2] * Math.PI / 180),    circleY - small_radius * (float) Math.cos(theta_values[2] * Math.PI / 180), 6, paint);//畫(huà)LOSE末尾小圓點(diǎn)   /*繪制文字*/  paintText.setColor(getResources().getColor(typedValue.resourceId));  paintText.setTextSize(small_radius * 2 / 3);  /*測(cè)量文字大小,確定繪制文字時(shí)垂直方向的位置*/  Paint.FontMetrics fontMetrics = paint.getFontMetrics();  float textBaseLineOffset = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;  /*在三個(gè)小圓的正中心位置繪制相應(yīng)的數(shù)字*/  canvas.drawText("" + (int)(mWinNumber * AnimCurrentValue), circleXs[0], circleY + textBaseLineOffset, paintText);  canvas.drawText("" + (int)(mDrawNumber * AnimCurrentValue), circleXs[1], circleY + textBaseLineOffset, paintText);  canvas.drawText("" + (int)(mLoseNumber * AnimCurrentValue), circleXs[2], circleY + textBaseLineOffset, paintText);  /*調(diào)整字體大小,繪制文本信息*/  paintText.setTextSize(small_radius * 4 / 9);  canvas.drawText("勝場(chǎng)", circleXs[0], circleY - small_radius*4/3, paintText);  canvas.drawText("平局", circleXs[1], circleY - small_radius*4/3, paintText);  canvas.drawText("負(fù)場(chǎng)", circleXs[2], circleY - small_radius*4/3, paintText);  /*20ms刷新一次數(shù)據(jù)*/  mHandler.postDelayed(mAnimation, 20);//啟動(dòng)動(dòng)畫(huà) }  public void setColor(int mColor) {  this.mColor = mColor;  invalidate(); }  public void setScore(int score) {  this.mScore = score;  invalidate(); }  public void setWinDrawLose(int win,int draw,int lose) {  this.mWinNumber = win;  this.mDrawNumber = draw;  this.mLoseNumber = lose;  mCurrentTime =0;  invalidate(); }}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 定日县| 靖边县| 潜江市| 孝昌县| 牡丹江市| 稷山县| 新乐市| 东明县| 沈丘县| 修武县| 万荣县| 滨海县| 东源县| 惠来县| 万安县| 安仁县| 四川省| 平安县| 明光市| 射阳县| 五寨县| 且末县| 得荣县| 潮安县| 锡林郭勒盟| 清镇市| 班玛县| 宁晋县| 武隆县| 怀仁县| 璧山县| 赤水市| 湄潭县| 阳山县| 安徽省| 永吉县| 水城县| 巴林右旗| 扎兰屯市| 仁化县| 册亨县|