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

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

Android 自定View實現(xiàn)仿QQ運動步數(shù)圓弧及動畫效果

2019-12-12 04:55:06
字體:
供稿:網(wǎng)友

在之前的Android超精準計步器開發(fā)-Dylan計步中的首頁用到了一個自定義控件,和QQ運動的界面有點類似,還有動畫效果,下面就來講一下這個View是如何繪制的。

1.先看效果圖

這里寫圖片描述

2.效果圖分析

功能說明:黃色的代表用戶設置的總計劃鍛煉步數(shù),紅色的代表用戶當前所走的步數(shù)。

初步分析:完全自定義View重寫onDraw()方法,畫圓弧。

3.畫一個圓弧必備知識

在Canvas中有一個畫圓弧的方法

drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//畫弧,

參數(shù)一是RectF對象,一個矩形區(qū)域橢圓形的界限用于定義在形狀、大小、電弧,

參數(shù)二是起始角(度)在電弧的開始,圓弧起始角度,單位為度。

參數(shù)三圓弧掃過的角度,順時針方向,單位為度,從右中間開始為零度。

參數(shù)四是如果是true(真)的話,在繪制圓弧時將圓心包括在內(nèi),通常用來繪制扇形;如果是false(假)這將是一個弧線。

參數(shù)五是Paint對象;

對于這個方法,大家可以看一下我手繪的草圖,比較爛,表達一下這幾個參數(shù)的意思和繪制過程,畫得不好望大家見諒!

這里寫圖片描述

4.繪圖的準備工作

(1).獲取中心點坐標

/**中心點的x坐標*/float centerX = (getWidth()) / 2;

(2).建立一個圓弧外的參考矩形

/**指定圓弧的外輪廓矩形區(qū)域*/RectF rectF = new RectF(0 + borderWidth, borderWidth, 2 * centerX - borderWidth, 2 * centerX - borderWidth);

5.繪圖的主要步驟

(1).【第一步】繪制整體的黃色圓弧

/*** 1.繪制總步數(shù)的黃色圓弧** @param canvas 畫筆* @param rectF 參考的矩形*/private void drawArcYellow(Canvas canvas, RectF rectF) {Paint paint = new Paint();/** 默認畫筆顏色,黃色 */paint.setColor(getResources().getColor(R.color.yellow));/** 結(jié)合處為圓弧*/paint.setStrokeJoin(Paint.Join.ROUND);/** 設置畫筆的樣式 Paint.Cap.Round ,Cap.SQUARE等分別為圓形、方形*/paint.setStrokeCap(Paint.Cap.ROUND);/** 設置畫筆的填充樣式 Paint.Style.FILL :填充內(nèi)部;Paint.Style.FILL_AND_STROKE :填充內(nèi)部和描邊; Paint.Style.STROKE :僅描邊*/paint.setStyle(Paint.Style.STROKE);/**抗鋸齒功能*/paint.setAntiAlias(true);/**設置畫筆寬度*/paint.setStrokeWidth(borderWidth);/**繪制圓弧的方法* drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//畫弧,參數(shù)一是RectF對象,一個矩形區(qū)域橢圓形的界限用于定義在形狀、大小、電弧,參數(shù)二是起始角(度)在電弧的開始,圓弧起始角度,單位為度。參數(shù)三圓弧掃過的角度,順時針方向,單位為度,從右中間開始為零度。參數(shù)四是如果這是true(真)的話,在繪制圓弧時將圓心包括在內(nèi),通常用來繪制扇形;如果它是false(假)這將是一個弧線,參數(shù)五是Paint對象;*/canvas.drawArc(rectF, startAngle, angleLength, false, paint);}

(2).【第二步】繪制當前進度的紅色圓弧

/*** 2.繪制當前步數(shù)的紅色圓弧*/private void drawArcRed(Canvas canvas, RectF rectF) {Paint paintCurrent = new Paint();paintCurrent.setStrokeJoin(Paint.Join.ROUND);paintCurrent.setStrokeCap(Paint.Cap.ROUND);//圓角弧度paintCurrent.setStyle(Paint.Style.STROKE);//設置填充樣式paintCurrent.setAntiAlias(true);//抗鋸齒功能paintCurrent.setStrokeWidth(borderWidth);//設置畫筆寬度paintCurrent.setColor(getResources().getColor(R.color.red));//設置畫筆顏色canvas.drawArc(rectF, startAngle, currentAngleLength, false, paintCurrent);}

(3).【第三步】繪制當前進度的紅色數(shù)字

/*** 3.圓環(huán)中心的步數(shù)*/private void drawTextNumber(Canvas canvas, float centerX) {Paint vTextPaint = new Paint();vTextPaint.setTextAlign(Paint.Align.CENTER);vTextPaint.setAntiAlias(true);//抗鋸齒功能vTextPaint.setTextSize(numberTextSize);Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);vTextPaint.setTypeface(font);//字體風格vTextPaint.setColor(getResources().getColor(R.color.red));Rect bounds_Number = new Rect();vTextPaint.getTextBounds(stepNumber, 0, stepNumber.length(), bounds_Number);canvas.drawText(stepNumber, centerX, getHeight() / 2 + bounds_Number.height() / 2, vTextPaint);}

(4).【第四步】繪制”步數(shù)”的紅色數(shù)字

/*** 4.圓環(huán)中心[步數(shù)]的文字*/private void drawTextStepString(Canvas canvas, float centerX) {Paint vTextPaint = new Paint();vTextPaint.setTextSize(dipToPx(16));vTextPaint.setTextAlign(Paint.Align.CENTER);vTextPaint.setAntiAlias(true);//抗鋸齒功能vTextPaint.setColor(getResources().getColor(R.color.grey));String stepString = "步數(shù)";Rect bounds = new Rect();vTextPaint.getTextBounds(stepString, 0, stepString.length(), bounds);canvas.drawText(stepString, centerX, getHeight() / 2 + bounds.height() + getFontHeight(numberTextSize), vTextPaint);}

6.動畫是如何實現(xiàn)的->ValueAnimator

ValueAnimator是整個屬性動畫機制當中最核心的一個類,屬性動畫的運行機制是通過不斷地對值進行操作來實現(xiàn)的,而初始值和結(jié)束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。它的內(nèi)部使用一種時間循環(huán)的機制來計算值與值之間的動畫過渡, 我們只需要將初始值和結(jié)束值提供給ValueAnimator,并且告訴它動畫所需運行的時長,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結(jié)束值這樣的效果。

/*為進度設置動畫* @param start 初始值* @param current 結(jié)束值* @param length 動畫時長*/private void setAnimation(float start, float current, int length) {ValueAnimator progressAnimator = ValueAnimator.ofFloat(start, current);progressAnimator.setDuration(length);progressAnimator.setTarget(currentAngleLength);progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {/**每次在初始值和結(jié)束值之間產(chǎn)生的一個平滑過渡的值,逐步去更新進度*/currentAngleLength = (float) animation.getAnimatedValue();invalidate();}});progressAnimator.start();}

7.整個自定義StepArcView的源碼

import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.RectF;import android.graphics.Typeface;import android.util.AttributeSet;import android.view.View;import cn.bluemobi.dylan.step.R;/*** Created by DylanAndroid on 2016/5/26.* 顯示步數(shù)的圓弧*/public class StepArcView extends View {/*** 圓弧的寬度*/private float borderWidth = 38f;/*** 畫步數(shù)的數(shù)值的字體大小*/private float numberTextSize = 0;/*** 步數(shù)*/private String stepNumber = "0";/*** 開始繪制圓弧的角度*/private float startAngle = 135;/*** 終點對應的角度和起始點對應的角度的夾角*/private float angleLength = 270;/*** 所要繪制的當前步數(shù)的紅色圓弧終點到起點的夾角*/private float currentAngleLength = 0;/*** 動畫時長*/private int animationLength = 3000;public StepArcView(Context context) {super(context);}public StepArcView(Context context, AttributeSet attrs) {super(context, attrs);}public StepArcView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);/**中心點的x坐標*/float centerX = (getWidth()) / 2;/**指定圓弧的外輪廓矩形區(qū)域*/RectF rectF = new RectF(0 + borderWidth, borderWidth, 2 * centerX - borderWidth, 2 * centerX - borderWidth);/**【第一步】繪制整體的黃色圓弧*/drawArcYellow(canvas, rectF);/**【第二步】繪制當前進度的紅色圓弧*/drawArcRed(canvas, rectF);/**【第三步】繪制當前進度的紅色數(shù)字*/drawTextNumber(canvas, centerX);/**【第四步】繪制"步數(shù)"的紅色數(shù)字*/drawTextStepString(canvas, centerX);}/*** 1.繪制總步數(shù)的黃色圓弧** @param canvas 畫筆* @param rectF 參考的矩形*/private void drawArcYellow(Canvas canvas, RectF rectF) {Paint paint = new Paint();/** 默認畫筆顏色,黃色 */paint.setColor(getResources().getColor(R.color.yellow));/** 結(jié)合處為圓弧*/paint.setStrokeJoin(Paint.Join.ROUND);/** 設置畫筆的樣式 Paint.Cap.Round ,Cap.SQUARE等分別為圓形、方形*/paint.setStrokeCap(Paint.Cap.ROUND);/** 設置畫筆的填充樣式 Paint.Style.FILL :填充內(nèi)部;Paint.Style.FILL_AND_STROKE :填充內(nèi)部和描邊; Paint.Style.STROKE :僅描邊*/paint.setStyle(Paint.Style.STROKE);/**抗鋸齒功能*/paint.setAntiAlias(true);/**設置畫筆寬度*/paint.setStrokeWidth(borderWidth);/**繪制圓弧的方法* drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//畫弧,參數(shù)一是RectF對象,一個矩形區(qū)域橢圓形的界限用于定義在形狀、大小、電弧,參數(shù)二是起始角(度)在電弧的開始,圓弧起始角度,單位為度。參數(shù)三圓弧掃過的角度,順時針方向,單位為度,從右中間開始為零度。參數(shù)四是如果這是true(真)的話,在繪制圓弧時將圓心包括在內(nèi),通常用來繪制扇形;如果它是false(假)這將是一個弧線,參數(shù)五是Paint對象;*/canvas.drawArc(rectF, startAngle, angleLength, false, paint);}/*** 2.繪制當前步數(shù)的紅色圓弧*/private void drawArcRed(Canvas canvas, RectF rectF) {Paint paintCurrent = new Paint();paintCurrent.setStrokeJoin(Paint.Join.ROUND);paintCurrent.setStrokeCap(Paint.Cap.ROUND);//圓角弧度paintCurrent.setStyle(Paint.Style.STROKE);//設置填充樣式paintCurrent.setAntiAlias(true);//抗鋸齒功能paintCurrent.setStrokeWidth(borderWidth);//設置畫筆寬度paintCurrent.setColor(getResources().getColor(R.color.red));//設置畫筆顏色canvas.drawArc(rectF, startAngle, currentAngleLength, false, paintCurrent);}/*** 3.圓環(huán)中心的步數(shù)*/private void drawTextNumber(Canvas canvas, float centerX) {Paint vTextPaint = new Paint();vTextPaint.setTextAlign(Paint.Align.CENTER);vTextPaint.setAntiAlias(true);//抗鋸齒功能vTextPaint.setTextSize(numberTextSize);Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);vTextPaint.setTypeface(font);//字體風格vTextPaint.setColor(getResources().getColor(R.color.red));Rect bounds_Number = new Rect();vTextPaint.getTextBounds(stepNumber, 0, stepNumber.length(), bounds_Number);canvas.drawText(stepNumber, centerX, getHeight() / 2 + bounds_Number.height() / 2, vTextPaint);}/*** 4.圓環(huán)中心[步數(shù)]的文字*/private void drawTextStepString(Canvas canvas, float centerX) {Paint vTextPaint = new Paint();vTextPaint.setTextSize(dipToPx(16));vTextPaint.setTextAlign(Paint.Align.CENTER);vTextPaint.setAntiAlias(true);//抗鋸齒功能vTextPaint.setColor(getResources().getColor(R.color.grey));String stepString = "步數(shù)";Rect bounds = new Rect();vTextPaint.getTextBounds(stepString, 0, stepString.length(), bounds);canvas.drawText(stepString, centerX, getHeight() / 2 + bounds.height() + getFontHeight(numberTextSize), vTextPaint);}/*** 獲取當前步數(shù)的數(shù)字的高度** @param fontSize 字體大小* @return 字體高度*/public int getFontHeight(float fontSize) {Paint paint = new Paint();paint.setTextSize(fontSize);Rect bounds_Number = new Rect();paint.getTextBounds(stepNumber, 0, stepNumber.length(), bounds_Number);return bounds_Number.height();}/*** dip 轉(zhuǎn)換成px** @param dip* @return*/private int dipToPx(float dip) {float density = getContext().getResources().getDisplayMetrics().density;return (int) (dip * density + 0.5f * (dip >= 0 ? 1 : -1));}/*** 所走的步數(shù)進度** @param totalStepNum 設置的步數(shù)* @param currentCounts 所走步數(shù)*/public void setCurrentCount(int totalStepNum, int currentCounts) {stepNumber = currentCounts + "";setTextSize(currentCounts);/**如果當前走的步數(shù)超過總步數(shù)則圓弧還是270度,不能成為園*/if (currentCounts > totalStepNum) {currentCounts = totalStepNum;}/**所走步數(shù)占用總共步數(shù)的百分比*/float scale = (float) currentCounts / totalStepNum;/**換算成弧度最后要到達的角度的長度-->弧長*/float currentAngleLength = scale * angleLength;/**開始執(zhí)行動畫*/setAnimation(0, currentAngleLength, animationLength);}/*** 為進度設置動畫* ValueAnimator是整個屬性動畫機制當中最核心的一個類,屬性動畫的運行機制是通過不斷地對值進行操作來實現(xiàn)的,* 而初始值和結(jié)束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。* 它的內(nèi)部使用一種時間循環(huán)的機制來計算值與值之間的動畫過渡,* 我們只需要將初始值和結(jié)束值提供給ValueAnimator,并且告訴它動畫所需運行的時長,* 那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結(jié)束值這樣的效果。** @param last* @param current*/private void setAnimation(float last, float current, int length) {ValueAnimator progressAnimator = ValueAnimator.ofFloat(last, current);progressAnimator.setDuration(length);progressAnimator.setTarget(currentAngleLength);progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {currentAngleLength = (float) animation.getAnimatedValue();invalidate();}});progressAnimator.start();}/*** 設置文本大小,防止步數(shù)特別大之后放不下,將字體大小動態(tài)設置** @param num*/public void setTextSize(int num) {String s = String.valueOf(num);int length = s.length();if (length <= 4) {numberTextSize = dipToPx(50);} else if (length > 4 && length <= 6) {numberTextSize = dipToPx(40);} else if (length > 6 && length <= 8) {numberTextSize = dipToPx(30);} else if (length > 8) {numberTextSize = dipToPx(25);}}}

8.用法說明

xml中

<cn.bluemobi.dylan.step.view.StepArcViewandroid:id="@+id/sv "android:layout_width="200dp"android:layout_height="200dp"android:layout_centerHorizontal="true"android:layout_marginTop="50dp" />

Activity中

StepArcView sv = (StepArcView) findViewById(R.id.sv);sv.setCurrentCount(7000, 1000);

以上所述是小編給大家介紹的Android 仿QQ運動步數(shù)圓弧及動畫效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網(wǎng)網(wǎng)站的支持!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 河曲县| 龙南县| 广州市| 锡林郭勒盟| 龙井市| 丹凤县| 栾川县| 开远市| 满城县| 信阳市| 乌拉特后旗| 耿马| 西乌| 益阳市| 泾川县| 遂宁市| 昌邑市| 公主岭市| 遂川县| 吉水县| 新沂市| 石嘴山市| 黔江区| 当涂县| 娱乐| 镇平县| 萨嘎县| 海安县| 环江| 云龙县| 南皮县| 诸城市| 舞钢市| 龙海市| 安阳市| 巢湖市| 揭西县| 铜鼓县| 清新县| 阿坝| 西盟|