English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
前のAndroid超精密カウントステップ開発-Dylanのステップカウントのホームページには、QQモバイルのインターフェースに似たカスタムコントロールが使用されており、アニメーション効果もあります。以下では、このViewがどのように描画されるかについて説明します。
1.まず効果図を見てみましょう
2.効果図分析
機能説明:黄色はユーザーが設定した総計歩数を、赤はユーザーが現在歩いた歩数を表します。
基本的な分析:完全にカスタマイズされたViewをonDraw()メソッドをオーバーライドして円弧を描画します。
3.円弧を描画するための必須知識
Canvasには円弧を描画する方法があります
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//円弧を描画
引数1はRectFオブジェクトで、形状、大きさ、円弧を定義するための矩形区域の椭圆形の境界です。
引数2は円弧の始まりの角度(度)で、円弧の始まり角度、単位は度です。
引数3は円弧が覆う角度で、時計回り方向、単位は度、右中央から0度开始です。
パラメータ4は、true(真)の場合、円弧を描画する際に円心を含めることができます。これは扇形を描画するために通常使用されます;false(偽)の場合、これは弧線となります。
引数5はPaintオブジェクト;
このメソッドについて、私の手描きスケッチをご覧ください。非常に悪いものですが、これらのパラメータの意味と描画プロセスを説明します。描画が悪いことをお許しください!
4.描画の準備
(1).中心点の座標を取得
/**中心点のx座標*/ float centerX = (getWidth()) / 2;
(2).円弧の外側の参照矩形を設定
/**円弧の外枠の矩形領域を指定*/ RectF rectF = new RectF(0 + borderWidth, borderWidth, 2 * centerX - borderWidth, 2 * centerX - borderWidth);
5.描画の主な手順
(1).【第1ステップ】全体の黄色い円弧を描画
/** * 1.黄色の円弧を全体のステップ数で描画 * * @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 :内部を塗りつぶす;Paint.Style.FILL_AND_STROKE :内部と縁を塗りつぶす; 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)//円弧を描画 引数1はRectFオブジェクトで、形状、大きさ、円弧を定義するための矩形区域の椭圆形の境界です。 引数2は円弧の始まりの角度(度)で、円弧の始まり角度、単位は度です。 引数3は円弧が覆う角度で、時計回り方向、単位は度、右中央から0度开始です。 引数4はこれはtrue(真)の場合、円弧を描画する際に円心を含める;これは扇形を描画するために通常使用されます;これはfalse(偽)の場合、これは弧線になります。 引数5はPaintオブジェクト; */ canvas.drawArc(rectF, startAngle, angleLength, false, paint); }
(2).【第2ステップ】現在の進捗の赤い円弧を描画
/** * 2.現在のステップの赤い円弧を描画 */ 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).【第3ステップ】現在の進捗の赤い数字を描画
/** * 3円環中心の歩数 */ 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).【第4ステップ】「ステップ数」の赤い数字を描画
/** * 4円環中心[歩数]の文字 */ 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 = "步数"; Rect bounds = new Rect(); vTextPaint.getTextBounds(stepString, 0, stepString.length(), bounds); canvas.drawText(stepString, centerX, getHeight()} / 2 + bounds.height() + getFontHeight(numberTextSize), vTextPaint); }
6.アニメーションはどのように実現されるか->ValueAnimator
ValueAnimatorは属性アニメーションメカニズムの中で最も核となるクラスであり、属性アニメーションの動作メカニズムは値に対する操作を繰り返し実現しており、初期値と終了値の間のアニメーション遷移はValueAnimatorクラスが計算する責任です。内部では時間ループのメカニズムを使用して値と値の間のアニメーション遷移を計算し、初期値と終了値を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) { /**初期値と終了値の間で生成される滑らかな過渡の値で、進捗を徐々に更新する*/ 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. * 显示步数的圆弧 */ public class StepArcView extends View { /** * 圆弧的宽度 */ private float borderWidth = 38f; /** * 画步数的数值的字体大小 */ private float numberTextSize = 0; /** * 步数 */ private String stepNumber = "0"; /** * 开始绘制圆弧的角度 */ private float startAngle = 135; /** * 终点对应的角度和起始点对应的角度的夹角 */ private float angleLength = 270; /** * 所要绘制的当前步数的红色圆弧终点到起点的夹角 */ 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; /**円弧の外枠の矩形領域を指定*/ RectF rectF = new RectF(0 + borderWidth, borderWidth, 2 * centerX - borderWidth, 2 * centerX - borderWidth); /**【第一歩】全体の黄色い円弧を描画*/ drawArcYellow(canvas, rectF); /**【第二歩】現在の進捗の赤い円弧を描画*/ drawArcRed(canvas, rectF); /**【第三歩】現在の進捗の赤い数字を描画*/ drawTextNumber(canvas, centerX); /**【第四歩】「ステップ数」の赤い数字を描画*/ drawTextStepString(canvas, centerX); } /** * 1.黄色の円弧を全体のステップ数で描画 * * @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 :内部を塗りつぶす;Paint.Style.FILL_AND_STROKE :内部と縁を塗りつぶす; 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)//円弧を描画 引数1はRectFオブジェクトで、形状、大きさ、円弧を定義するための矩形区域の椭圆形の境界です。 引数2は円弧の始まりの角度(度)で、円弧の始まり角度、単位は度です。 引数3は円弧が覆う角度で、時計回り方向、単位は度、右中央から0度开始です。 引数4はこれはtrue(真)の場合、円弧を描画する際に円心を含める;これは扇形を描画するために通常使用されます;これはfalse(偽)の場合、これは弧線になります。 引数5はPaintオブジェクト; */ canvas.drawArc(rectF, startAngle, angleLength, false, paint); } /** * 2.現在のステップの赤い円弧を描画 */ 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円環中心の歩数 */ 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円環中心[歩数]の文字 */ 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 = "步数"; Rect bounds = new Rect(); vTextPaint.getTextBounds(stepString, 0, stepString.length(), bounds); canvas.drawText(stepString, centerX, getHeight()} / 2 + bounds.height() + getFontHeight(numberTextSize), vTextPaint); } /** * 現在の歩数の数字の高さを取得 * * @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)); } /** * 歩数の進捗 * * @param totalStepNum 設定された歩数 * @param currentCounts 歩数 */ public void setCurrentCount(int totalStepNum, int currentCounts) { stepNumber = currentCounts + ""; setTextSize(currentCounts); /**現在の歩数が合計歩数を超えた場合、円弧はどうなるか270度、園としてはなりません*/ if (currentCounts > totalStepNum) { currentCounts = totalStepNum; } /**歩数の合計歩数に対する占める割合*/ float scale = (float) currentCounts / totalStepNum; /**最終的に到達する角度の長さに変換する必要があります。-->弧長*/ float currentAngleLength = scale * angleLength; /**アニメーションを開始*/ setAnimation(0, currentAngleLength, animationLength); } /** * 進捗をアニメーションに設定 * ValueAnimatorは属性アニメーションメカニズムの中で最も核心的なクラスであり、属性アニメーションは値に対する操作を繰り返し実行することで実現されます。 * 初期値と終了値の間のアニメーション遷移は、ValueAnimatorクラスが担当しています。 * 内部では、時間ループのメカニズムを使用して、値と値の間のアニメーション遷移を計算します。 * 私たちは初期値と終了値を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(); } /** * テキストのサイズを設定し、歩数が非常に大きくなった場合に文字が収まらないことを防ぎ、フォントのサイズを動的に設定します。 * * @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運動歩数円弧及びアニメーション効果であり、皆さんに役立つことを願っています。何か疑問があれば、コメントを残してください。編集者は皆さんの質問に迅速に回答します。また、この「はげ叫び教程」サイトへのサポートに感謝しています。
声明:本文の内容はインターネットから収集され、著作権者に帰属します。インターネットユーザーが自発的に貢献し、アップロードした内容であり、本サイトは所有権を持ちません。また、人間による編集は行われておらず、関連する法的責任も負いません。著作権侵害が疑われる内容がある場合は、メールを送信して:notice#w までお知らせください。3codebox.com(メール送信時は、#を@に変更してください。報告を行い、関連する証拠を提供してください。一旦確認がついたら、本サイトは侵害される内容をすぐに削除します。)