Android 자체 보기 QQ 운동 걸음 수 원호 및 애니메이션 효과 구현
1.효과 도 를 먼저 본다
2.효과 도 분석
기능 설명:노란색 은 사용자 가 설정 한 총 계획 단련 걸음 수 를 대표 하고 빨간색 은 사용자 가 현재 가 고 있 는 걸음 수 를 대표 합 니 다.
초보 분석:View 재 작성 onDraw()방법 을 완전히 사용자 정의 하고 원 호 를 그립 니 다.
3.원 호 를 그 리 는 데 필요 한 지식
Canvas 에서 원 호 를 그 리 는 방법 이 있어 요.
drawArc(RectF oval,float startAngle,float sweepAngle,boolean useCenter,Paint paint)//그림 호,
매개 변 수 는 RectF 대상 이 고 사각형 구역 의 타원형 경 계 는 모양,크기,전호 에 정의 합 니 다.
매개 변수 두 번 째 는 시작 각(도)이 전호 의 시작,원호 의 시작 각도,단 위 는 도 이다.
매개 변수 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.
*
* @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)// ,
RectF , 、 、 ,
( ) , , 。
, , , 。
true( ) , , ; false( ) ,
Paint ;
*/
canvas.drawArc(rectF, startAngle, angleLength, false, paint);
}
(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.
*/
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.애니메이션 이 어떻게 이 루어 졌 는 지->ValueAnimatorValueAnimator 는 전체 속성 애니메이션 체제 에서 가장 핵심 적 인 유형 으로 속성 애니메이션 의 운영 체 제 는 끊임없이 값 을 조작 함으로써 이 루어 진 것 이 고 초기 값 과 끝 값 간 의 애니메이션 과 도 는 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)// ,
RectF , 、 、 ,
( ) , , 。
, , , 。
true( ) , , ; false( ) ,
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" />
활동 중
StepArcView sv = (StepArcView) findViewById(R.id.sv);
sv.setCurrentCount(7000, 1000);
위 에서 말 한 것 은 소 편 이 여러분 에 게 소개 한 안 드 로 이 드 모방 QQ 운동 걸음 수 원호 와 애니메이션 효과 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 저 에 게 메 시 지 를 남 겨 주세요.소 편 은 신속하게 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.