안 드 로 이 드 아이 치 이 를 모방 하여 애니메이션 인 스 턴 스 를 불 러 옵 니 다.
효과 그림:
사용 한 지식 포인트:
애니메이션 해체
4
여기 서 어 려 운 점 은 주로 좌표 에 대한 계산 입 니 다.다음 에 제 가 상세 하 게 말씀 드 리 겠 습 니 다.
4.567917.우 리 는 여기 서 원심 을 x,y 축의 출발점 으로 하고 아래 방향 은 x 축의 정방 향 이 며 오른쪽 방향 은 y 축의 정방 향 이다.view 의 크기 가 등 폭 이 높 으 면 이 럴 때 원 의 반지름 을 너비 나 높이 의 절반 으로 설정 할 수 있 습 니 다.등 폭 이 높 지 않 으 면 너비 나 높이 의 최소 값 의 절반 을 원 의 반지름 으로 해 야 합 니 다4.567917.다음은 삼각형 이자 좌 표를 확정 하 는 난점 이다.이 삼각형 은 등변 삼각형 이다.우 리 는 삼각형 이 회전 할 때 도 원심 을 돌 며 회전 하 기 를 바란다.그래서 원심 에서 삼각형 의 각 정점 까지 의 거 리 는 모두 같다.내 가 여기 설치 한 것 은 삼각형 의 길이 가 원 의 반지름 이다
이 그림 을 꺼 냈 다 고 믿 고 사인,코사인 함수,p1,p2,p3 의 좌표 도 나 왔 습 니 다.
p1.x = -(int) ((radius / 2 * Math.tan(30 * Math.PI / 180)));
p1.y = -radius / 2;
p2.x = p1.x;
p2.y = radius / 2;
p3.x = (int) (radius / 2 / Math.sin(60 * Math.PI / 180));
p3.y = 0;
일부 속성 정의
private static final String DEFAULT_COLOR = "#00ba9b";
private static final int DEFAULT_SIZE = 50; //
private static final int DRAW_CIRCLE = 10001; //
private static final int ROTATE_TRIANGLE = 10002; //
private Context mContext;
private Paint trianglePaint; //
private Paint circlePaint; //
private float paintStrokeWidth = 1; //
private long duration = 800; //
private int mWidth; //View
private int mHeight;
private Path trianglePath; //
private Path circlePath; //
private Path dst; // pathMeasure path
private Point p1, p2, p3; //
private ValueAnimator animator; // 0-1
private float mAnimatorValue = 0; // 0-1
private int mCurrentState = 0; //
private int radius = 0; //
private float startSegment; //
private PathMeasure mMeasure; // path
private int triangleColor = -1;
private int circleColor = -1;
path 설정1.삼각형 은 항상 존재 하기 때문에 먼저 삼각형 을 그리고 path 로 그립 니 다.우 리 는 삼각형 의 세 정점 의 좌 표를 알 고 삼각형 을 그리 기 가 쉬 워 집 니 다.
trianglePath = new Path();
p1 = new Point();
p2 = new Point();
p3 = new Point();
trianglePath.moveTo(p1.x, p1.y);
trianglePath.lineTo(p2.x, p2.y);
trianglePath.lineTo(p3.x, p3.y);
trianglePath.close();
이렇게 삼각형 path 가 설정 되 어 있 습 니 다.canvans.drawPath()를 호출 하면 삼각형 을 캔버스 에 그 릴 수 있 습 니 다.2.그 다음 에 원 을 그립 니 다.앞에서 말 했 듯 이 원 은 구멍 이 있 습 니 다.여기 서도 원 을 path 에 추가 합 니 다.canvas 위 에 직접 그리 지 않 은 이 유 는 뒤에 원 의 둘레 를 계산 해 야 하기 때 문 입 니 다.이런 조작 path 는 우 리 를 도와 조작 할 것 입 니 다.
circlePath = new Path();
RectF circleRect = new RectF(-radius, -radius, radius, radius);
circlePath.addArc(circleRect, 268, 358); // 268° , 258°
속성 애니메이션 설정애니메이션 은 0-1 의 데이터 가 필요 하기 때 문 입 니 다.
여기 서 우 리 는 속성 애니메이션 이 우리 에 게 제공 하 는 수 치 를 빌려 애니메이션 을 실현 합 니 다.
private void initAnimation() {
TimeInterpolator timeInterpolator = new AccelerateDecelerateInterpolator();
animator = ValueAnimator.ofFloat(0, 1).setDuration(duration);
animator.setInterpolator(timeInterpolator);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mAnimatorValue = (float) animation.getAnimatedValue(); // 0-1
invalidate(); //
}
});
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
// ,
switch (mCurrentState) {
case DRAW_CIRCLE:
mCurrentState = ROTATE_TRIANGLE;
break;
case ROTATE_TRIANGLE:
mCurrentState = DRAW_CIRCLE;
break;
default:
break;
}
}
});
}
onDrawonDraw 방법 분석
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//
canvas.translate(mWidth / 2, mHeight / 2);
// path dst
dst.reset();
//
switch (mCurrentState) {
//
case DRAW_CIRCLE:
// path(dst) , ,
// , 1/5, ,
// 0-1 0.3 。
startSegment = (float) (mMeasure.getLength() / 5 * ((0.3 - mAnimatorValue) > 0 ? (0.3 - mAnimatorValue) : 0));
//
trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawPath(trianglePath, trianglePaint);
// , , ,
// path, path(dst), reset, ,
// dst ( , dst path ,
// false, dst dst , )
mMeasure.getSegment(startSegment, mMeasure.getLength() * mAnimatorValue, dst, true);
canvas.drawPath(dst, circlePaint);
break;
//
case ROTATE_TRIANGLE:
// , ,
canvas.save();
//
trianglePaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.rotate(360 * mAnimatorValue);
canvas.drawPath(trianglePath, trianglePaint);
//
canvas.restore();
// , , 0-1 ,
// ,
mMeasure.getSegment(mMeasure.getLength() * mAnimatorValue, mMeasure.getLength(), dst, true);
canvas.drawPath(dst, circlePaint);
break;
default:
break;
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.