안 드 로 이 드 아이 치 이 를 모방 하여 애니메이션 인 스 턴 스 를 불 러 옵 니 다.

이 글 은 안 드 로 이 드 가 아이 치 이 를 모방 하여 애니메이션 인 스 턴 스 를 불 러 왔 습 니 다.구체 적 인 코드 는 다음 과 같 습 니 다.
효과 그림:

사용 한 지식 포인트:
  • Path
  • ValueAnimator
  • Path 와 ValueAnimator 에 대해 아직 익숙 하지 않다 면 이 몇 개의 큰 신 들 의 Blog 사용자 정의 view 를 보 는 것 을 추천 합 니 다.현재 저 에 게 가장 적합 한 글,사용자 정의 view 의 상세 한 튜 토리 얼 과 실천 입 니 다.이것 도 튜 토리 얼 과 실천 입 니 다.그들의 노력 에 감 사 드 립 니 다!(잘 보시 고 많은 깨 우 침 을 얻 으 셨 으 면 좋 겠 습 니 다.
    애니메이션 해체
    4
  • 원 하 나 를 시계 방향 으로 천천히 그린다(원 은 닫 힌 원 이 아니다)
  • 4.567917.이 단 계 는 조합 애니메이션 으로 원 이 천천히 사라 지 는 동시에 삼각형 은 시계 방향 으로 회전한다.

    여기 서 어 려 운 점 은 주로 좌표 에 대한 계산 입 니 다.다음 에 제 가 상세 하 게 말씀 드 리 겠 습 니 다.
    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;
            }
          }
        });
      }
    
    
    onDraw
    onDraw 방법 분석
    
    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;
        }
    
      }
    
    
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기