안 드 로 이 드 360 시장 다운로드 버튼 의 실현 방법

우선 효과 도 를 살 펴 보 자.

아무리 복잡 한 애니메이션 이라도 우 리 는 작은 단원 으로 나 누 어 단계별 로 실현 할 수 있다.이 애니메이션 은 대개 수축,준비,불 러 오기,완성 몇 부분 으로 나 뉜 다.이 를 위해 view 의 상 태 를 설명 하기 위해 매 거 진 클래스 를 정의 합 니 다.

public enum Status { NORMAL, START, PRE, EXPAND, LOAD, END }
수축 애니메이션
애니메이션 을 사용 하여 원 각 사각형 의 폭 을 계속 바 꾸 고 다시 그립 니 다.코드 는 다음 과 같 습 니 다:

private void initAnim() {
 Animation animation1 = new Animation() {
 @Override
 protected void applyTransformation(float interpolatedTime, Transformation t) {
 mCurrLength = mWidth * (1 - interpolatedTime);
 if (mCurrLength < mHeight) {
  mCurrLength = mHeight;
  clearAnimation();
  mAngleAnim.start();
 }
 invalidate();
 }
 };

 animation1.setDuration(mShrinkDuration);
 animation1.setInterpolator(new LinearInterpolator());
 animation1.setAnimationListener(new Animation.AnimationListener() {
 @Override
 public void onAnimationStart(Animation animation) {
 mStatus = Status.START;
 }

 @Override
 public void onAnimationEnd(Animation animation) {

 }

 @Override
 public void onAnimationRepeat(Animation animation) {

 }
 });
 mShrinkAnim = animation1;
 ...
}
onDraw 에서 그리 기:

if (mStatus == Status.START || mStatus == Status.NORMAL) {
 float left = (mWidth - mCurrLength) / 2f;
 float right = (mWidth + mCurrLength) / 2f;
 float r = mHeight / 2f;
 canvas.drawRoundRect(new RectF(left, 0, right, mHeight), r, r, mBgPaint);
 if (mStatus == Status.NORMAL) {
 Paint.FontMetrics fm = mTextPaint.getFontMetrics();
 float y = mHeight / 2 + (fm.descent - fm.ascent) / 2 - fm.descent;
 canvas.drawText("  ", mWidth / 2, y, mTextPaint);
 }
 }
애니메이션 준비
이때 회전 애니메이션 은 canvas 를 통 해 배경 원 과 세 개의 작은 원 을 그린 다음 에 캔버스 를 계속 회전 시 켜 서 이 루어 진 것 이다.구체 적 으로 원심 좌표 와 각도 애니메이션 을 구하 면 우 리 는 코드 를 직접 볼 수 있다.

ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 @Override
 public void onAnimationUpdate(ValueAnimator animation) {
 mAngle += mPreAnimSpeed;
 invalidate();
 }
 });
 animator.addListener(new Animator.AnimatorListener() {
 @Override
 public void onAnimationStart(Animator animation) {
 mStatus = Status.PRE;
 }

 @Override
 public void onAnimationEnd(Animator animation) {
 mAngleAnim.cancel();
 startAnimation(mTranslateAnim);
 }

 @Override
 public void onAnimationCancel(Animator animation) {

 }

 @Override
 public void onAnimationRepeat(Animator animation) {

 }
 });

 animator.setDuration(mPreAnimDuration);
 animator.setInterpolator(new LinearInterpolator());
 mAngleAnim = animator;
onDraw 에서 코드 그리 기:

if (mStatus == Status.PRE) {
 canvas.drawCircle(mWidth / 2f, mHeight / 2f, mHeight / 2f, mBgPaint);
 canvas.save();
 mTextPaint.setStyle(Paint.Style.FILL);
 canvas.rotate(mAngle, mWidth / 2, mHeight / 2);
 //        
 float cX = mWidth / 2f;
 float cY = mHeight / 2f;
 float radius = mHeight / 2 / 3f;
 canvas.drawCircle(cX, cY, radius, mTextPaint);
 //       
 float rr = radius / 2f;
 float cYY = mHeight / 2 - (radius + rr / 3);
 canvas.drawCircle(cX, cYY, rr, mTextPaint);
 //      
 float cXX = (float) (cX - Math.sqrt(2) / 2f * (radius + rr / 3f));
 cYY = (float) (mHeight / 2 + Math.sqrt(2) / 2f * (radius + rr / 3f));
 canvas.drawCircle(cXX, cYY, rr, mTextPaint);
 //      
 cXX = (float) (cX + Math.sqrt(2) / 2f * (radius + rr / 3f));
 canvas.drawCircle(cXX, cYY, rr, mTextPaint);
 canvas.restore();
 }
애니메이션 펼 치기
애니메이션 을 펼 치 는 것 도 view 의 폭 을 계속 바 꾸 고 원 각 사각형 을 다시 그 리 는 동시에 애니메이션 을 준비 하 는 상 태 를 오른쪽으로 이동 해 야 합 니 다.

Animation animator1 = new Animation() {
 @Override
 protected void applyTransformation(float interpolatedTime, Transformation t) {
 mCurrLength = mHeight + (mWidth - mHeight) * interpolatedTime;
 mTranslationX = (mWidth - mHeight) / 2 * interpolatedTime;
 invalidate();
 }
 };
 animator1.setAnimationListener(new Animation.AnimationListener() {
 @Override
 public void onAnimationStart(Animation animation) {
 mStatus = Status.EXPAND;
 }

 @Override
 public void onAnimationEnd(Animation animation) {
 clearAnimation();
 mLoadAngleAnim.start();
 mMovePointAnim.start();
 }

 @Override
 public void onAnimationRepeat(Animation animation) {

 }
 });
 animator1.setDuration(mExpandAnimDuration);
 animator1.setInterpolator(new LinearInterpolator());
 mTranslateAnim = animator1;
onDraw 에서 코드 그리 기

if (mStatus == Status.EXPAND) {
 float left = (mWidth - mCurrLength) / 2f;
 float right = (mWidth + mCurrLength) / 2f;
 float r = mHeight / 2f;
 canvas.drawRoundRect(new RectF(left, 0, right, mHeight), r, r, mBgPaint);
 canvas.save();
 mTextPaint.setStyle(Paint.Style.FILL);
 canvas.translate(mTranslationX, 0);
 //        
 float cX = mWidth / 2f;
 float cY = mHeight / 2f;
 float radius = mHeight / 2 / 3f;
 canvas.drawCircle(cX, cY, radius, mTextPaint);
 //       
 float rr = radius / 2f;
 float cYY = mHeight / 2 - (radius + rr / 3);
 canvas.drawCircle(cX, cYY, rr, mTextPaint);
 //      
 float cXX = (float) (cX - Math.sqrt(2) / 2f * (radius + rr / 3f));
 cYY = (float) (mHeight / 2 + Math.sqrt(2) / 2f * (radius + rr / 3f));
 canvas.drawCircle(cXX, cYY, rr, mTextPaint);
 //      
 cXX = (float) (cX + Math.sqrt(2) / 2f * (radius + rr / 3f));
 canvas.drawCircle(cXX, cYY, rr, mTextPaint);
 canvas.restore();
 }
애니메이션 불 러 오기
애니메이션 을 불 러 오 는 것 은 세 부분 으로 나 뉘 는데 오른쪽 회전 애니메이션,사인 궤적 운동 의 작은 공 애니메이션,진도 가 업 데 이 트 된 애니메이션 이다.사인 애니메이션 은 사인 함수 의 주기,y 축 오프셋,x 축 오프셋 을 요구한다.

ValueAnimator animator2 = ValueAnimator.ofFloat(0, 1);
 animator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
 @Override
 public void onAnimationUpdate(ValueAnimator animation) {
 mLoadAngle += mLoadRotateAnimSpeed;
 invalidate();
 }
 });
 animator2.addListener(new Animator.AnimatorListener() {
 @Override
 public void onAnimationStart(Animator animation) {
 mStatus = Status.LOAD;
 }

 @Override
 public void onAnimationEnd(Animator animation) {
 mLoadAngleAnim.cancel();
 }

 @Override
 public void onAnimationCancel(Animator animation) {

 }

 @Override
 public void onAnimationRepeat(Animator animation) {

 }
 });
 animator2.setDuration(Integer.MAX_VALUE);
 animator2.setInterpolator(new LinearInterpolator());
 mLoadAngleAnim = animator2;
onDraw 에서 코드 그리 기:

if (mStatus == Status.LOAD || mStatus == Status.END) {
 float left = (mWidth - mCurrLength) / 2f;
 float right = (mWidth + mCurrLength) / 2f;
 float r = mHeight / 2f;
 mBgPaint.setColor(mProgressColor);
 canvas.drawRoundRect(new RectF(left, 0, right, mHeight), r, r, mBgPaint);
 if (mProgress != 100) {
 for (int i = 0; i < mFourMovePoints.length; i++) {
  if (mFourMovePoints[i].isDraw)
  canvas.drawCircle(mFourMovePoints[i].moveX, mFourMovePoints[i].moveY, mFourMovePoints[i].radius, mTextPaint);
 }
 }
 float progressRight = mProgress * mWidth / 100f;
 mBgPaint.setColor(mBgColor);
 canvas.save();
 canvas.clipRect(0, 0, progressRight, mHeight);
 canvas.drawRoundRect(new RectF(left, 0, right, mHeight), r, r, mBgPaint);
 canvas.restore();

 if (mProgress != 100) {
 canvas.drawCircle(mWidth - mHeight / 2, mHeight / 2, mHeight / 2, mBgPaint);
 canvas.save();
 mTextPaint.setStyle(Paint.Style.FILL);
 canvas.rotate(mLoadAngle, mWidth - mHeight / 2, mHeight / 2);
 canvas.drawCircle(mWidth - mHeight + 30, getCenterY(mWidth - mHeight + 30, 5), 5, mTextPaint);
 canvas.drawCircle(mWidth - mHeight + 45, getCenterY(mWidth - mHeight + 45, 8), 8, mTextPaint);
 canvas.drawCircle(mWidth - mHeight + 68, getCenterY(mWidth - mHeight + 68, 11), 11, mTextPaint);
 canvas.drawCircle(mWidth - mHeight + 98, getCenterY(mWidth - mHeight + 98, 14), 14, mTextPaint);
 canvas.restore();
 }

 Paint.FontMetrics fm = mTextPaint.getFontMetrics();
 float y = mHeight / 2 + (fm.descent - fm.ascent) / 2 - fm.descent;
 canvas.drawText(mProgress + "%", mWidth / 2, y, mTextPaint);
 }
프로젝트 홈 페이지:http://www.open-open.com/lib/view/home/1494985743108
로 컬 다운로드:http://xiazai.jb51.net/201705/yuanma/Metal626-360DownLoadView(jb51.net).rar
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기