亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

 更新時間:2016年10月28日 09:28:14   作者:DylanAndroid  
這篇文章主要介紹了Android自定義view實現(xiàn)高仿QQ運動步數(shù)圓弧及動畫效果的實例代碼,本文涉及到繪制圓弧需要具備的知識點,需要的朋友可以參考下

在之前的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));
/** 結合處為圓弧*/
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)的,而初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。它的內(nèi)部使用一種時間循環(huán)的機制來計算值與值之間的動畫過渡, 我們只需要將初始值和結束值提供給ValueAnimator,并且告訴它動畫所需運行的時長,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結束值這樣的效果。

/*為進度設置動畫
* @param start 初始值
* @param current 結束值
* @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() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
/**每次在初始值和結束值之間產(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);
}
@Override
protected 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));
/** 結合處為圓弧*/
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 轉換成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)的,
* 而初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。
* 它的內(nèi)部使用一種時間循環(huán)的機制來計算值與值之間的動畫過渡,
* 我們只需要將初始值和結束值提供給ValueAnimator,并且告訴它動畫所需運行的時長,
* 那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結束值這樣的效果。
*
* @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() {
@Override
public 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.StepArcView
android: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)站的支持!

相關文章

  • Android?Scroller實現(xiàn)彈性滑動效果

    Android?Scroller實現(xiàn)彈性滑動效果

    這篇文章主要為大家詳細介紹了Android?Scroller實現(xiàn)彈性滑動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 簡述Android中SELinux的TE

    簡述Android中SELinux的TE

    SELinux使用類型強制來改進強制訪問控制。這篇文章給大家介紹了Android中SELinux的TE的相關知識,感興趣的朋友一起看看吧
    2018-03-03
  • Android中實現(xiàn)長按修改ListView對象的內(nèi)容

    Android中實現(xiàn)長按修改ListView對象的內(nèi)容

    這篇文章主要給大家介紹了在Android中實現(xiàn)長按修改ListView對象內(nèi)容的相關資料,文中給出了完整的示例代碼,相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。
    2017-02-02
  • Kotlin擴展函數(shù)及實現(xiàn)機制的深入探索

    Kotlin擴展函數(shù)及實現(xiàn)機制的深入探索

    擴展函數(shù)與擴展屬性的神奇之處在于,可以在不修改原來類的條件下,使用函數(shù)和屬性,表現(xiàn)得就像是屬于這個類的一樣。下面這篇文章主要給大家介紹了關于Kotlin擴展函數(shù)及實現(xiàn)機制的相關資料,需要的朋友可以參考下
    2018-06-06
  • 如何使用SurfaceView實現(xiàn)魚兒游動動畫

    如何使用SurfaceView實現(xiàn)魚兒游動動畫

    這篇文章主要教大家如何使用SurfaceView實現(xiàn)魚兒游動動畫,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 配置Android SDK

    配置Android SDK

    今天小編就為大家分享一篇關于配置Android SDK的文章,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • 從源碼編譯Android系統(tǒng)的Java類庫和JNI動態(tài)庫的方法

    從源碼編譯Android系統(tǒng)的Java類庫和JNI動態(tài)庫的方法

    這篇文章主要介紹了從源碼編譯Android系統(tǒng)的Java類庫和JNI動態(tài)庫的方法,例子基于Linux系統(tǒng)環(huán)境下來講,需要的朋友可以參考下
    2016-02-02
  • 分享Android微信紅包插件

    分享Android微信紅包插件

    這篇文章為大家準備了Android微信紅包插件,輕輕松松幫助大家實現(xiàn)微信紅包功能,感興趣的小伙伴們可以參考一下
    2015-12-12
  • Kotlin標準庫函數(shù)使用分析及介紹

    Kotlin標準庫函數(shù)使用分析及介紹

    Kotlin提供了一個系統(tǒng)庫,是Java庫的增強。其中有很多函數(shù)在適配了Java的類型和方法同時使用Kotlin的語法。其中一些底層的函數(shù) 是使用比較廣泛的
    2022-09-09
  • Flutter實現(xiàn)笑嘻嘻的動態(tài)表情的示例代碼

    Flutter實現(xiàn)笑嘻嘻的動態(tài)表情的示例代碼

    這篇文章主要為大家介紹了如何利用Flutter實現(xiàn)笑嘻嘻的動態(tài)表情,文中的示例代碼講解詳細,對我們學習Flutter有一定幫助,感興趣的可以了解一下
    2022-04-04

最新評論