아주 간단 하고 멋 진 LoadingView 애니메이션 효과
6804 단어 LoadingView애니메이션
LoadingView 는 다음 그림 과 유사 합 니 다:
실 현 된 코드 도 복잡 하지 않 습 니 다.바로 작은 공의 운동 궤적 을 계산 해 야 합 니 다.제 가 직접 계산 한 그림 을 그 렸 습 니 다.아주 간단 한 것 은 삼각함수 의 사용 입 니 다.
그 다음 에 코드 는 코드 가 실현 되 었 고 주요 내용 은 모두 주석 이 있 습 니 다.코드 는 다음 과 같 습 니 다.
public class LoadingView extends View {
private final static String TAG = "LoadingView";
private final static int LEFT_BALL_DOWN = 1;
private final static int LEFT_BALL_UP = 2;
private final static int RIGHT_BALL_DOWN = 3;
private final static int RIGHT_BALL_UP = 4;
private Paint paint1, paint2, paint3, paint4, paint5;
private int mCurrentAnimatorValue;
private int circleRadius = 10; //
private int distance = 60; //
private int mCurrentState = LEFT_BALL_DOWN;
public LoadingView(Context context) {
super(context);
init(context);
}
public LoadingView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public LoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
paint1 = getPaint(Color.RED);
paint2 = getPaint(Color.YELLOW);
paint3 = getPaint(Color.GREEN);
paint4 = getPaint(Color.BLUE);
paint5 = getPaint(Color.CYAN);
ValueAnimator animator = ValueAnimator.ofInt(0, 90);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mCurrentAnimatorValue = (int) animation.getAnimatedValue();
Log.e(TAG, "onAnimationUpdate : mCurrentAnimatorValue = " + mCurrentAnimatorValue);
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) {
Log.e(TAG, "onAnimationRepeat : mCurrentAnimatorValue = " + mCurrentAnimatorValue);
switch (mCurrentState) {
case LEFT_BALL_DOWN:
mCurrentState = RIGHT_BALL_UP;
break;
case RIGHT_BALL_UP:
mCurrentState = RIGHT_BALL_DOWN;
break;
case RIGHT_BALL_DOWN:
mCurrentState = LEFT_BALL_UP;
break;
case LEFT_BALL_UP:
mCurrentState = LEFT_BALL_DOWN;
break;
}
}
});
animator.setStartDelay(500);
animator.setDuration(600);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setInterpolator(new DecelerateInterpolator());
animator.start();
}
private Paint getPaint(int color) {
Paint paint = new Paint();
paint.setColor(color);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
return paint;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x, y;
double cosValue = Math.cos(PI * mCurrentAnimatorValue / 180);
double sinValue = Math.sin(PI * mCurrentAnimatorValue / 180);
drawFourBall(canvas);
switch (mCurrentState) {
case LEFT_BALL_DOWN://
x = circleRadius + (int) ((distance - circleRadius) * (1 - cosValue));
y = getHeight() - distance + (int) ((distance - circleRadius) * sinValue);
canvas.drawCircle(x, y, circleRadius, paint1);
break;
case RIGHT_BALL_UP://
x = distance + 8 * circleRadius + (int) ((distance - circleRadius) * sinValue);
y = getHeight() - distance + (int) (cosValue * (distance - circleRadius));
canvas.drawCircle(x, y, circleRadius, paint5);
break;
case RIGHT_BALL_DOWN://
x = distance + 8 * circleRadius + (int) ((distance - circleRadius) * (cosValue));
y = (getHeight() - distance) + (int) ((distance - circleRadius) * (sinValue));
canvas.drawCircle(x, y, circleRadius, paint5);
break;
case LEFT_BALL_UP://
x = distance - (int) ((distance - circleRadius) * sinValue);
y = getHeight() - distance + (int) ((distance - circleRadius) * cosValue);
canvas.drawCircle(x, y, circleRadius, paint1);
break;
}
}
private void drawFourBall(Canvas canvas) {
int y = getHeight() - circleRadius;
canvas.drawCircle(distance + 2 * circleRadius, y, circleRadius, paint2);
canvas.drawCircle(distance + 4 * circleRadius, y, circleRadius, paint3);
canvas.drawCircle(distance + 6 * circleRadius, y, circleRadius, paint4);
if (mCurrentState == LEFT_BALL_DOWN || mCurrentState == LEFT_BALL_UP) {// ,
canvas.drawCircle(distance + 8 * circleRadius, y, circleRadius, paint5);
} else if (mCurrentState == RIGHT_BALL_UP || mCurrentState == RIGHT_BALL_DOWN) {// ,
canvas.drawCircle(distance, y, circleRadius, paint1);
}
}
}
실현 의 효 과 는 그림 1 과 같 고 문제 가 있 으 면 서로 토론 한다.마지막 으로 xml 파일 을 붙 이면 loadingview 의 크기 와 색상 같은 인 자 를 보완 합 니 다.xml 는 다음 과 같 습 니 다:
<com.define_view.LoadingView
android:layout_marginTop="20px"
android:background="#999999"
android:layout_width="200px"
android:layout_height="200px" />
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
FloatingActionButton의 애니메이션을 만드는 MotionSpec은 무엇입니까?의 3일째는 주식회사 에이팀 라이프 스타일 나고야 개발부 의 가 담당합니다! 라이프 스타일로 몇 안되는 앱 엔지니어이므로 이번에도 앱의 기사로 가겠습니다! 자사 앱에서 FloatingActionButton을 추가했을...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.