ObjectAnimator 속성 애니메이션 소스 분석 편

13741 단어 androidobjectAnimator
또 여러분 과 만 났 습 니 다.요 며칠 동안 프로젝트 를 하 느 라 바 빠 서 블 로 그 를 업데이트 하지 않 았 습 니 다.그리고 소스 코드 를 보 려 면 블 로그 나 필 기 를 해 야 한 다 는 것 을 알 게 되 었 습 니 다.그 전에 필 자 는 Value Animator 와 Object Animator 의 소스 코드 를 보 았 습 니 다.그런데 며칠 밖 에 지나 지 않 아 다른 일 을 하면 거의 잊 어 버 렸 습 니 다.지금 다시 한 번 봐 야 돼 요.너무 아파 요.
또한 필 자 는 이미 약서 에 속성 애니메이션 에 관 한 비교적 체계 적 인 상세 한 글 을 썼 고 그 후에 CSDN 에 다시 쓸 것 이다(다시 쓰 는 것 이지 과 거 를 복사 하 는 것 이 아니다.처음 쓰 는 것 이 너무 엉망 이기 때문이다-=).
자,더 이상 말다툼 하지 않 겠 습 니 다.오늘 하고 싶 은 말 인 Object Animator 의 소스 코드 분석(사용 부분)을 살 펴 보 겠 습 니 다.
ObjectAnimator 사용 부분 소스 코드
우 리 는 모두 속성 애니메이션 의 사용 이 세 부분 으로 나 뉘 는 것 을 알 고 있다.생 성,속성 추가,시작 이다.오늘 우리 가 말 하고 자 하 는 것 은 속성 을 만 들 고 추가 하 는 것 입 니 다.먼저 만 든 소스 코드 를 살 펴 보 겠 습 니 다.
창설
우선 오늘 사용 한 모든 배경 을 살 펴 보 자.
작은 공의 이동 효 과 를 실현 하기 위해 사용자 정의 View―PointView 를 썼 습 니 다.PointView 코드 는 다음 과 같 습 니 다(보지 않 아 도 됩 니 다-.+):

public class PointView extends View {
  private Point mCurrentPoint;
  private Paint paint;
  /**
   *       
   **/
  public PointView(Context context) {
    super(context);
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.CYAN);
    paint.setStrokeWidth(5);
    paint.setStyle(Paint.Style.STROKE);
  }
  public PointView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.CYAN);
    paint.setStrokeWidth(5);
    paint.setStyle(Paint.Style.STROKE);
  }
  /**
   * onDraw      ,  mCurrentPoint  ,   Point  ,
   *        drawPoint  
   **/
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (mCurrentPoint == null) {
      mCurrentPoint = new Point(500, 500);
      drawPoint(canvas);
    } else {
      drawPoint(canvas);
    }
  }
  //           
  public void setMove(Point point) {
    mCurrentPoint = point;
    invalidate();
  }
  //    
  private void startAnimation() {
    ObjectAnimator animator = ObjectAnimator.ofObject(PointView.this, "Move", new BallEvaluator(),
        new Point(500, 500),
        new Point(500, 800), new Point(700, 800));
    animator.setInterpolator(new LinearInterpolator());
    animator.setDuration(5000);
    animator.start();
  }
  //        ,     ,         。
  public void moveBall() {
    startAnimation();
  }
  private void drawPoint(Canvas canvas) {
    canvas.drawCircle(mCurrentPoint.getX(), mCurrentPoint.getY(), 30, paint);
  }
  //        
  public class BallEvaluator implements TypeEvaluator<Point> {
    float x;
    float y;
    @Override
    public Point evaluate(float fraction, Point startValue, Point endValue) {
      float startX = startValue.getX();
      float startY = startValue.getY();
      float endX = endValue.getX();
      float endY = endValue.getY();
      x = fraction * (endX - startX);
      y = fraction * (endY - startY);
      Log.e("ASDSAD", "x = " + x + "y = " + y);
      return new Point(startX + x, startY + y);
    }
  }
}
코드 가 좀 많 을 수 있 지만 이것 은 중요 한 것 이 아 닙 니 다.오늘 우리 가 주목 하 는 것 은 속성 애니메이션 일 뿐 입 니 다.그래서 우 리 는 안에 있 는 startAnimation 방법 과 setMove 방법 만 보면 됩 니 다.
  • setMove:속성 애니메이션 ObjectAnimator 류 는 property Name 을 대응 하 는 set 방법 으로 연결 한 다음 에 반사 체 제 를 통 해 이 방법 을 호출 하 는 것 을 알 기 때문에 우 리 는 대응 하 는 set 방법 이 필요 합 니 다
  • 4.567917.startAnimation:이 방법 은 우리 의 애니메이션 을 설정 하고 애니메이션 을 시작 하 는 데 사 용 됩 니 다.setMove 방법 은 매우 간단 합 니 다.우 리 는 들 어 오 는 새로운 작은 공의 대상 을 mCurrent Ball 에 할당 한 다음 에 invalidate 방법 으로 다시 그립 니 다.startAnimation 방법 을 살 펴 보 겠 습 니 다.
    
    ObjectAnimator animator = ObjectAnimator.ofObject(PointView.this, "Move", new BallEvaluator(),
            new Point(500, 500),
            new Point(500, 800), new Point(700, 800));
        animator.setInterpolator(new LinearInterpolator());
        animator.setDuration(5000);
        animator.start();
    오 브 젝 트 에 먼저 들 어 가 는 방법 을 살 펴 보 겠 습 니 다.
    
    public static ObjectAnimator ofObject(Object target, String propertyName,
          TypeEvaluator evaluator, Object... values) {
        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
        anim.setObjectValues(values);
        anim.setEvaluator(evaluator);
        return anim;
      }
    우 리 는 ofObject 가 정적 인 방법 이라는 것 을 발견 했다.그 는 안에서 Object Animator 대상 을 만 들 었 다.그리고 setObjeectValues 와 setEvaluator 방법 을 호출 하여 각각 데이터 와 평가 기 를 추가 했다.
    바로 이 오 브 젝 트 안에 세 개의 입구 가 우리 가 들 어가 기 를 기다 리 고 있다.
    ObjectAnimator 의 구조 방법setObjectValues 방법setEvaluator 방법
    그럼 오 브 젝 트 애 니 메 이 터 의 구조 부터 살 펴 보 자.
    ObjectAnimator 구조 방법:
    
      private ObjectAnimator(Object target, String propertyName) {
        setTarget(target);
        setPropertyName(propertyName);
      }
    또 두 가지 방법 입 니 다.하 나 는 보 러 갑 니 다.먼저 setTarget 에 들 어 갑 니 다.
    
      @Override
      public void setTarget(@Nullable Object target) {
        final Object oldTarget = getTarget();
        if (oldTarget != target) {
          if (isStarted()) {
            cancel();
          }
          mTarget = target == null ? null : new WeakReference<Object>(target);
          // New target should cause re-initialization prior to starting
          mInitialized = false;
        }
      }
    이 코드 들 은 모두 무슨 뜻 인지 알 수 있다.이 방법 은 우리 가 두 가지 만 주의해 야 한다.
  • 우 리 는 들 어 오 는 target 을 mTarget 이라는 약 한 인용 에 전달 했다
  • mInitialized = false;이 속성 을 우 리 는 이렇게 이해 할 수 있 습 니 다.그의 ObjectAnimator 가 준비 되 지 않 았 을 때(초기 화 과정 이 완성 되 지 않 았 을 때)그 는 줄곧 false 였 습 니 다
  • 이 방법 은 뛰 어 넘 었 다.
    그리고 setProperty Name 방법 을 봅 니 다.
    
      public void setPropertyName(@NonNull String propertyName) {
        // mValues could be null if this is being constructed piecemeal. Just record the
        // propertyName to be used later when setValues() is called if so.
        if (mValues != null) {
          PropertyValuesHolder valuesHolder = mValues[0];
          String oldName = valuesHolder.getPropertyName();
          valuesHolder.setPropertyName(propertyName);
          mValuesMap.remove(oldName);
          mValuesMap.put(propertyName, valuesHolder);
        }
        mPropertyName = propertyName;
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
      }
    먼저 mValues 와 mValuesMap 이라는 두 속성 을 소개 합 니 다.그들 은 모두 Property ValueHolder 의 속성 을 저장 하고 저 장 된 것 은 모두 같 습 니 다.다만 mValuesMap 은 property Name 을 통 해 해당 하 는 Property ValueHolder 를 찾 을 수 있 습 니 다.
    
    PropertyValuesHolder[] mValues;
    HashMap<String, PropertyValuesHolder> mValuesMap;
    이 방법 은 Property Name 을 Property Value Holder 에 넣 는 것 입 니 다.
    이제 우리 의 Object Animator 구조 방법 을 다 보 았 습 니 다.우 리 는 이어서 setObject Values 방법 을 보 겠 습 니 다.
    anim.setObjectValues:
    
      @Override
      public void setObjectValues(Object... values) {
        if (mValues == null || mValues.length == 0) {
          // No values yet - this animator is being constructed piecemeal. Init the values with
          // whatever the current propertyName is
          if (mProperty != null) {
            setValues(PropertyValuesHolder.ofObject(mProperty, (TypeEvaluator) null, values));
          } else {
            setValues(PropertyValuesHolder.ofObject(mPropertyName,
                (TypeEvaluator) null, values));
          }
        } else {
          super.setObjectValues(values);
        }
      }
    이 코드 의 전체적인 논 리 는 하나 입 니 다.mValues 가 값 이 없 으 면 setValues 방법 을 호출 합 니 다.그렇지 않 으 면 부모 클래스 의 setObject Values 방법 을 호출 합 니 다.
    어 지 러 워,진정 해!  우 리 는 처음 만 든 대상 이기 때문에 비어 있 을 것 입 니 다.그래서 우 리 는 setValues 방법 만 보면 됩 니 다.하지만 주의 하 세 요.여기에 Property Value Holder 도 있 습 니 다.그래서 우 리 는 Property Value Holder 의 of Object 방법 을 먼저 보기 로 했 습 니 다.
    PropertyValueHolder.ofObject:
    
      public static <V> PropertyValuesHolder ofObject(Property property,
          TypeEvaluator<V> evaluator, V... values) {
        PropertyValuesHolder pvh = new PropertyValuesHolder(property);
        pvh.setObjectValues(values);
        pvh.setEvaluator(evaluator);
        return pvh;
      }
    위의 Object Animator 의 of Object 와 차이 가 많 지 않 습 니 다.우 리 는 더 이상 말 하지 않 겠 습 니 다.선택 할 수 있 는 두 가지 길이 있 습 니 다.
  • setObjectValues
  • setEvaluator
  • setObjectValues 먼저 보기:
    PropertyValueHolder.setObjectValues:
    
      public void setObjectValues(Object... values) {
        mValueType = values[0].getClass();
        mKeyframes = KeyframeSet.ofObject(values);
        if (mEvaluator != null) {
          mKeyframes.setEvaluator(mEvaluator);
        }
      }
    다 들 토 할 것 같은 거 알 아 요.지금 KeyFrames 가 또 나 왔어요.두피 가 저 려 요.그 렇 죠?진정 하 세 요.버 텨 요!
    이 KeyFrames 는 KeyFrameSet 의 인터페이스 입 니 다.KeyframeSet 의 ofObject 방법 을 살 펴 보 겠 습 니 다.
    KeyframeSet.ofObject 방법:
    
      public static KeyframeSet ofObject(Object... values) {
        int numKeyframes = values.length;
        ObjectKeyframe keyframes[] = new ObjectKeyframe[Math.max(numKeyframes,2)];//           ObjectKeyFrame  
        if (numKeyframes == 1) {
          keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f);
          keyframes[1] = (ObjectKeyframe) Keyframe.ofObject(1f, values[0]);
        } else {
          keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f, values[0]);
          for (int i = 1; i < numKeyframes; ++i) {
            keyframes[i] = (ObjectKeyframe) Keyframe.ofObject((float) i / (numKeyframes - 1), values[i]);
          }
        }
        return new KeyframeSet(keyframes);
      }
    우 리 는 마침내 비교적 익숙 한 유형 을 보 았 다.KeyFrame,이 관건 적 인 프레임 이라는 유형 이 마침내 나 타 났 다.우 리 는 이 방법 을 간단하게 분석 했다.
    우선 최소 두 자리 인 ObjectKeyFrame 대상 을 만 든 다음 values 의 길 이 를 판단 하고,한 값 만 있 으 면 유일한 값 을 마지막(이때 가 두 번 째)에 추가 하거나,그렇지 않 으 면 순서대로 추가 합 니 다.마지막 으로 ObjectKeyFrame 의 배열 을 KeyFrameSet 형식 으로 변환 하여 되 돌려 줍 니 다.
    이제 Property Value Holder 의 setObject Values 방법 으로 돌아 가 겠 습 니 다.다음은 setEvaluator 방법 을 살 펴 보 겠 습 니 다.
    KeyFrameSet.setEvaluator 방법:
    
      public void setEvaluator(TypeEvaluator evaluator) {
        mEvaluator = evaluator;
      }
    이것 은 더 말 할 필요 도 없 이 바로 지나 간다.
    이제 우리 의 Property Value Holder 의 of Object 방법 을 다 보 았 습 니 다.우 리 는 anim.setObject Values 방법 으로 돌아 가 setValues 방법 을 보 겠 습 니 다.
    setValues:
    
      public void setValues(PropertyValuesHolder... values) {
        int numValues = values.length;
        mValues = values;
        mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
        for (int i = 0; i < numValues; ++i) {
          PropertyValuesHolder valuesHolder = values[i];
          mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
      }
    이것 은 완전히 우리 가 방금 말 한 Property Value Holder 의 두 속성 mValues 와 mValuesMap 에 데 이 터 를 추가 하 는 과정 입 니 다.
    이제 우 리 는 마지막 큰 방법 만 남 았 다.anim.set Evaluator,흥분!!
    anim.setEvaluator 방법:
    
      public void setEvaluator(TypeEvaluator value) {
        if (value != null && mValues != null && mValues.length > 0) {
          mValues[0].setEvaluator(value);
        }
      }
    이 방법 은 모든 Property Value Holder 대상 에 게 setEvaluator 방법 을 실행 하 는 것 입 니 다.이 방법 을 눌 러 보 겠 습 니 다.
    PropertyValueHolder.setEvaluator 방법:
    
      public void setEvaluator(TypeEvaluator evaluator) {
        mEvaluator = evaluator;
        mKeyframes.setEvaluator(evaluator);
      }
    키 프레임 의 setEvaluator 에 들 어 갔 습 니 다.키 프레임 set 의 setEvaluator 방법 을 살 펴 보 겠 습 니 다.
    KeyFrameSet.setEvaluator 방법:
    
      public void setEvaluator(TypeEvaluator evaluator) {
        mEvaluator = evaluator;
      }
    이 방법 은 말 할 필요 가 없다.
    마지막 으로 우 리 는 만 든 anim 의 대상 으로 돌 아 왔 습 니 다.지금까지 우 리 는 우리 가 원 하 는 Object Animator 대상 을 얻 었 습 니 다.
    이 과정 은 좀 번거롭다.우 리 는 지금 여러 번 생각 을 해 보 자.
    ObjectAnimator.of Object 를 호출 한 후
  • 먼저 new ObjectAnimator 대상 은 ObjectAnimator 의 구조 방법 에 들 어 갑 니 다.구조 방법 에서 우 리 는 두 가지 방법 을 실 행 했 습 니 다.setTarget 과 setProperty Name
  • 그리고 ObjectAnimator 의 setObjectValues 방법 을 호출 했다.이 방법 에서 우 리 는 먼저 Property ValueHolder 대상 을 예화 한 다음 에 setValues 방법 으로 Property ValueHolder 를 전달한다
  • 4.567917.이후 ObjectAnimator 의 set Evaluator 방법 을 호출 했 습 니 다.평가 기 를 추 가 했 습 니 다
  • 마지막 으로 ObjectAnimator 대상 으로 돌 아 왔 습 니 다.
  • 여기까지 오 브 젝 트 애 니 메 이 터 대상 인 스 턴 스 생 성 을 완 료 했 습 니 다.
    여기 서 만 든 부분 이 모두 완성 되 었 습 니 다.다음은 속성 을 추가 하 는 것 을 보 겠 습 니 다.이것 은 아주 간단 합 니 다.
    속성 추가
    우리 한 가지 방법 을 예 로 들 자.setInterpolator 방법 을 예 로 들 자.
    
      public void setInterpolator(TimeInterpolator value) {
        if (value != null) {
          mInterpolator = value;
        } else {
          mInterpolator = new LinearInterpolator();
        }
      }
    이 방법 은 우리 가 플러그 인 을 추가 하 는 방법 입 니 다.우 리 는 그 가 mInterpolator 에 만 값 을 부여 하 는 것 임 을 알 게 되 었 습 니 다.만약 에 비어 있 으 면 선형 플러그 인 을 추가 합 니 다.
    다른 속성 을 추가 하 는 방법 은 set Duration,set RepeatCount 등 이 모두 이와 같 으 니 내 려 가서 직접 보 세 요.
    아직 staruML 을 사용 할 줄 모 르 기 때문에 아직 타 이 밍 을 한 장 도 보 내지 않 았 습 니 다.

    총결산
    이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.더 많은 내용 을 알 고 싶다 면 아래 링크 를 보 세 요.

    좋은 웹페이지 즐겨찾기