속성 애니메이션 개요

Compose 방식 사용해 보기
Jetpack Compose는 Android에 권장되는 UI 도구 키트입니다. Compose에서 애니메이션을 사용하는 방법을 알아보세요.
<ph type="x-smartling-placeholder"></ph> animate*AsState → 를 통해 개인정보처리방침을 정의할 수 있습니다.

속성 애니메이션 시스템은 강력한 프레임워크로 거의 모든 것에 애니메이션을 적용할 수 있습니다. 애니메이션을 정의하여 시간이 지남에 따라 객체 속성을 변경할 수 있습니다. 단일 객체를 반환할 수 있습니다. 속성 애니메이션은 속성의 (객체의 필드) 값을 보여줍니다. 무언가를 애니메이션으로 표시하려면 애니메이션으로 보여줄 객체 속성(예: 화면상의 객체 위치, 기간) 애니메이션을 적용할 값도 지정할 수 있습니다.

속성 애니메이션 시스템을 사용하면 애니메이션:

  • 재생 시간: 애니메이션 재생 시간을 지정할 수 있습니다. 기본 길이는 300ms입니다.
  • 시간 보간 유형: 속성 값이 함수입니다.
  • 반복 횟수 및 동작: 재생 시간의 끝에 도달하고 애니메이션을 반복할 횟수에 도달합니다. 그 외에 애니메이션을 역방향으로 재생할지 여부를 지정합니다. 역재생으로 설정 반복 횟수에 도달할 때까지 애니메이션이 앞뒤로 반복됩니다.
  • 애니메이터 세트: 애니메이션을 함께 재생하거나 지연 시간을 측정합니다
  • 프레임 새로고침 지연: 애니메이션 프레임의 새로 고침 빈도를 지정할 수 있습니다. 이 기본값은 10ms마다 새로 고침하도록 설정되어 있지만 애플리케이션이 프레임을 새로 고칠 수 있는 속도는 궁극적으로 시스템의 전반적인 사용량과 시스템이 기본 타이머를 처리하는 속도에 따라 달라집니다.

속성 애니메이션의 전체 예는 다음을 참고하세요. CustomTransitionChangeColor 클래스 를 참조하세요.

속성 애니메이션 작동 방식

먼저 간단한 예를 사용하여 애니메이션 작동 방식을 살펴보겠습니다. 그림 1은 객체를 나타내는 x 속성으로 애니메이션되는 가상의 객체입니다. 화면의 가로 위치입니다. 애니메이션 재생 시간은 40ms로 설정되고 40픽셀입니다. 기본 프레임 새로고침 빈도인 10ms마다 가로 10픽셀로 확대합니다. 40ms가 끝나면 애니메이션이 중지되고 객체는 가로 위치 40. 이것은 선형 보간을 사용한 애니메이션의 예입니다. 즉, 물체가 일정한 속도로 움직입니다.

그림 1. 선형 애니메이션의 예

비선형 보간을 사용하도록 애니메이션을 지정할 수도 있습니다. 그림 2는 가속하고 감속하는 지점에서 감속하는 가상의 객체를 말합니다. 종료되어야 합니다. 객체는 여전히 40ms 동안 40픽셀 만큼 움직이지만 비선형입니다. 이 애니메이션은 시작 지점에서 중간 지점까지는 가속하다가 중간 지점에서 애니메이션이 끝날 때까지 기다립니다. 그림 2에서 볼 수 있듯이 중간보다 짧습니다.

그림 2. 비선형 애니메이션의 예

속성 애니메이션 시스템의 중요한 구성요소가 위의 그림과 같은 애니메이션을 계산합니다. 그림 3은 기본 클래스가 협력 관계에 있습니다

그림 3. 애니메이션 계산 방법

ValueAnimator 객체는 애니메이션의 타이밍을 추적합니다. 애니메이션이 실행된 시간, 실행 중인 속성의 현재 값 등 있습니다.

ValueAnimator는 애니메이션 보간 유형을 정의하는 TimeInterpolator와 표시할 속성의 값을 계산하는 방법을 정의하는 TypeEvaluator를 캡슐화합니다. 애니메이션 예를 들어, 그림 2에서 사용된 TimeInterpolator는 다음과 같습니다. AccelerateDecelerateInterpolatorTypeEvaluatorIntEvaluator입니다.

애니메이션을 시작하려면 ValueAnimator를 만들고 애니메이션을 적용할 속성의 시작 및 끝 값과 함께 지정할 수 있습니다. start()를 호출하면 시작합니다 전체 애니메이션 중에 ValueAnimator경과 비율을 계산합니다. 0과 1 사이로 변경할 수 있습니다. 이 경과된 비율은 애니메이션이 완료된 시간의 비율을 나타내며 0은 0%를 의미합니다. 1은 100%를 의미합니다. 예를 들어, 그림 1에서 t = 10ms에서 경과된 비율은 0.25입니다. 총 지속 시간이 t = 40ms이기 때문입니다.

ValueAnimator가 경과된 비율을 계산하면 현재 설정된 TimeInterpolator를 호출하여 보간된 비율. 보간된 비율은 경과된 비율을 새 설정된 시간 보간을 고려한 비율입니다. 예를 들어, 그림 2에서는 애니메이션이 느리게 가속되므로 보간된 비율인 약 0 .15가 t = 10ms에서 경과된 비율(0.25) 그림 1에서 보간된 비율은 항상 다음과 동일합니다. 경과된 비율입니다.

보간된 비율을 계산할 때 ValueAnimator는 다음을 호출합니다. 적절한 TypeEvaluator를 사용하여 보간된 비율, 시작 값 및 종료 값을 설정합니다. 예를 들어, 그림 2에서 보간된 비율은 t = 0.15였습니다. 10밀리초이므로 이 시점의 속성 값은 0 .15 × (40 - 0) 또는 6이 됩니다.

속성 애니메이션과 보기 애니메이션의 차이점

뷰 애니메이션 시스템은 View에만 애니메이션을 적용하는 기능을 제공합니다. 객체이므로 View가 아닌 객체에 애니메이션을 적용하려면 그렇게 할 수 있습니다 보기 애니메이션 시스템 또한 조정 및 조정과 같은 View 객체의 몇 가지 측면을 노출하여 애니메이션을 적용합니다. 회전할 수 있습니다.

뷰 애니메이션 시스템의 또 다른 단점은 실제 뷰 자체가 아니라 뷰가 그려졌습니다. 예를 들어 버튼을 움직이도록 애니메이션을 적용한 경우 버튼이 올바르게 그려지지만 버튼을 클릭할 수 있는 실제 위치는 버튼은 변경되지 않으므로 이를 처리할 자체 로직을 구현해야 합니다.

속성 애니메이션 시스템을 사용하면 이러한 제약 조건이 완전히 삭제되며, 애니메이션 효과를 통해 객체의 모든 속성 (뷰 및 뷰가 아닌)과 객체 자체는 실제로 수정됩니다. 속성 애니메이션 시스템은 애니메이션을 수행하는 방식에서도 더 강력합니다. 위치 상위 수준에서 애니메이션으로 보여줄 속성에 애니메이터를 할당합니다(예: 색상, 색상,). 보간, 크기 등의 애니메이션 요소를 정의할 수 있습니다 여러 애니메이터의 동기화입니다.

그러나 보기 애니메이션 시스템은 설정하는 데 시간이 덜 소요되고 작성해야 할 코드가 적습니다. 뷰 애니메이션으로 필요한 모든 작업을 수행하거나 기존 코드가 이미 원하는 방식으로 작동하지만 속성 애니메이션 시스템을 사용할 필요가 없습니다. 또한 두 애니메이션 시스템을 모두 사용하는 것이 좋습니다.

API 개요

속성 애니메이션 시스템의 API 중 대부분은 android.animation에서 찾을 수 있습니다. 뷰 애니메이션 시스템은 이미 android.view.animation에 여러 보간기를 정의하므로 보간기도 사용할 수 있습니다. 다음 표에서는 주요 구성요소 내에 있습니다.

Animator 클래스는 있습니다. 이 클래스는 최소한의 리소스만 제공하므로 일반적으로 직접 사용하지 않습니다. 기능입니다. 다음 서브클래스는 Animator를 확장합니다.

표 1. 애니메이터

클래스 설명
ValueAnimator 속성 애니메이션의 기본 타이밍 엔진으로, 속성을 지정합니다. 애니메이션을 계산하는 핵심 기능을 모두 갖추고 있습니다. 각 애니메이션의 타이밍 세부정보, 애니메이션 반복, 업데이트 이벤트를 수신하는 리스너, 사용자 지정 평가합니다. 속성에 애니메이션을 적용하는 데는 두 가지 요소가 있는데, 하나는 애니메이션된 속성을 계산하는 것입니다. 값을 설정하고 해당 값을 애니메이션으로 보여주는 객체 및 속성에서 설정합니다. ValueAnimator은 두 번째 곡을 나오지 않으므로 반드시 들어보세요. ValueAnimator 및 애니메이션을 적용할 객체를 자체 로직으로 수정할 수 있습니다. 다음 섹션을 참조하세요. 자세한 내용은 ValueAnimator로 애니메이션 적용을 참조하세요.
ObjectAnimator 타겟을 설정할 수 있는 ValueAnimator의 서브클래스 객체 및 객체 속성을 사용하여 애니메이션을 적용할 수 있습니다. 이 클래스는 다음 시점에 따라 속성을 업데이트합니다. 애니메이션의 새 값을 계산합니다. 다음을 사용할 대상: 대부분 ObjectAnimator, 대상 객체의 값에 애니메이션을 적용하는 것이 훨씬 더 쉬워지기 때문입니다. 하지만 ObjectAnimator에는 특정 요구사항이 있는 것과 같은 몇 가지 추가 제한사항이 있으므로 ValueAnimator를 직접 사용하려는 경우가 있습니다. 접근자 메서드를 정의합니다.
AnimatorSet 애니메이션이 함께 실행될 수 있도록 애니메이션을 그룹화하는 메커니즘을 제공합니다. 관계될 수 있습니다 애니메이션이 함께 재생되거나, 순차적으로 재생되거나, 끝난 후에 재생되도록 설정할 수 있습니다. 지정할 수 있습니다 여러 부문 조합에 대한 섹션 참조 애니메이터 세트를 사용한 애니메이션을 참조하세요.

평가자는 속성 애니메이션 시스템에 주어진 속성 Animator에서 제공하는 타이밍 데이터를 사용합니다. 클래스, 애니메이션의 시작 및 종료 값을 계산하고 애니메이션으로 표시되는 속성 값을 계산합니다. 기반으로 합니다. 속성 애니메이션 시스템에서는 다음 평가자를 제공합니다.

표 2. 평가자

클래스/인터페이스 설명
IntEvaluator int 속성의 값을 계산하는 기본 평가자입니다.
FloatEvaluator float 속성의 값을 계산하는 기본 평가자입니다.
ArgbEvaluator 표시되는 색상 속성의 값을 계산하는 기본 평가자입니다. 16진수 값으로 표현됩니다.
TypeEvaluator 고유 평가자를 생성하는 데 사용할 수 있는 인터페이스입니다. 애니메이션 효과를 int, float 또는 색상이 아닌 객체 속성 TypeEvaluator 인터페이스를 구현하여 을 사용하여 객체 속성의 애니메이션 값을 계산합니다. int, float, 색상에 맞춤 TypeEvaluator를 지정할 수도 있습니다. 값에도 적용됩니다. 자세한 내용은 TypeEvaluator 사용 섹션을 참조하세요. 커스텀 평가자 작성 방법에 관한 정보

시간 보간기는 애니메이션의 특정 값이 시간 함수입니다. 예를 들어 전체 화면에서 선형으로 발생하도록 애니메이션을 지정할 수 있습니다. 애니메이션이 전체 시간 동안 균일하게 움직이도록 하거나, 사용자가 직접 애니메이션을 비선형 시간을 사용합니다. 예를 들어 초기에는 가속하고 종료되어야 합니다. 표 3에서는 android.view.animation에 포함된 보간을 설명합니다. 제공된 보간기 중 적합한 것이 없는 경우 필요에 따라 TimeInterpolator 인터페이스를 구현하고 직접 만듭니다. 맞춤 함수를 작성하는 방법에 관한 자세한 내용은 보간 사용을 참고하세요. 보간기입니다.

표 3. 보간기

클래스/인터페이스 설명
AccelerateDecelerateInterpolator 변경 속도가 느리게 시작했다가 끝나지만 속도가 빠른 보간입니다. 표시됩니다.
AccelerateInterpolator 변경 속도가 느리게 시작된 다음 가속화합니다.
AnticipateInterpolator 변경이 역방향으로 시작된 다음 신속하게 정방향으로 진행되는 보간입니다.
AnticipateOvershootInterpolator 변경이 역방향으로 시작된 다음 신속하게 정방향으로 진행되어 넘어갑니다. 마지막으로 최종 값으로 돌아갑니다.
BounceInterpolator 변경이 끝에서 앞뒤로 왔다갔다하는 보간입니다.
CycleInterpolator 애니메이션이 지정된 주기 동안 반복되는 보간입니다.
DecelerateInterpolator 변경 속도가 빠르게 시작된 후 감속합니다.
LinearInterpolator 변경 속도가 일정한 보간입니다.
OvershootInterpolator 변경이 정방향으로 신속하게 진행되어 마지막 값을 넘어선 보간기입니다. 확인할 수 있습니다
TimeInterpolator 고유 보간을 구현하는 데 사용할 수 있는 인터페이스입니다.

ValueAnimator를 사용하여 애니메이션화

ValueAnimator 클래스를 사용하면 int, float 또는 색상 집합을 지정하여 애니메이션 재생 시간 지정 값을 포함합니다. 다음 중 하나를 호출하여 ValueAnimator을 얻습니다. 팩토리 메서드 ofInt(), ofFloat() 또는 ofObject()입니다. 예를 들면 다음과 같습니다.

Kotlin

ValueAnimator.ofFloat(0f, 100f).apply {
    duration = 1000
    start()
}

자바

ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);
animation.setDuration(1000);
animation.start();

이 코드에서 ValueAnimatorstart() 메서드가 실행될 때 1,000ms 동안 0~100 사이의 값을 반환합니다.

다음을 수행하여 애니메이션으로 보여줄 맞춤 유형도 지정할 수 있습니다.

Kotlin

ValueAnimator.ofObject(MyTypeEvaluator(), startPropertyValue, endPropertyValue).apply {
    duration = 1000
    start()
}

자바

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();

이 코드에서 ValueAnimatorstartPropertyValue부터 endPropertyValue까지 애니메이션으로 표현됩니다. start() 메서드가 실행될 때 1, 000ms 동안 MyTypeEvaluator에서 공급한 논리.

애니메이션의 값을 사용하려면 AnimatorUpdateListenerValueAnimator 객체에 추가합니다. 다음 코드를 참조하세요.

Kotlin

ValueAnimator.ofObject(...).apply {
    ...
    addUpdateListener { updatedAnimation ->
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        textView.translationX = updatedAnimation.animatedValue as Float
    }
    ...
}

자바

animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

onAnimationUpdate()에 있음 메서드의 경우 업데이트된 애니메이션 값에 액세스하여 이 값을 둘 중 하나입니다. 리스너에 대한 자세한 내용은 애니메이션 리스너

ObjectAnimator를 사용하여 애니메이션화

ObjectAnimator는 이전 섹션에서 설명한 ValueAnimator의 서브클래스이며 타이밍을 결합합니다. ValueAnimator 엔진 및 가치 계산을 통해 대상 객체의 이름이 지정된 속성에 애니메이션을 적용합니다. 이렇게 하면 한 번에 여러 개의 객체를 더 이상 ValueAnimator.AnimatorUpdateListener를 구현할 필요가 없으므로 이는 애니메이션 속성이 자동으로 업데이트되기 때문입니다.

ObjectAnimator를 인스턴스화하는 것은 ValueAnimator와 비슷하지만 객체와 그 객체의 속성 이름도 지정합니다 (예: 문자열)과 함께 애니메이션으로 표시할 값을 포함합니다.

Kotlin

ObjectAnimator.ofFloat(textView, "translationX", 100f).apply {
    duration = 1000
    start()
}

자바

ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);
animation.setDuration(1000);
animation.start();

ObjectAnimator 업데이트 속성 사용 다음을 수행해야 합니다.

  • 애니메이션화할 객체 속성에는 set<PropertyName>() ObjectAnimator 애니메이션이 실행되는 동안 속성이 자동으로 업데이트되기 때문에 속성에 액세스할 수 있어야 합니다. 이 setter 메서드를 사용합니다. 예를 들어 속성 이름이 foo이면 setFoo() 메서드가 있어야 합니다. 이 setter 메서드가 존재하지 않는 경우 옵션: <ph type="x-smartling-placeholder">
      </ph>
    • 적절한 권한이 있으면 클래스에 setter 메서드를 추가합니다.
    • 변경할 권한이 있는 래퍼 클래스를 사용하고 해당 래퍼가 값을 유효한 setter 메서드로 가져와서 원래 객체에 전달합니다.
    • 대신 ValueAnimator를 사용하세요.
  • ObjectAnimator 팩토리 메서드 중 하나에서 values... 매개변수에 하나의 값만 지정하면 이 값이 애니메이션을 적용할 수 있습니다. 따라서 애니메이션화할 객체 속성에는 getter 함수가 있어야 합니다. 애니메이션의 시작 값을 가져오는 데 사용됩니다. getter 함수는 get<PropertyName>() 형태입니다. 예를 들어 속성 이름이 foo에는 getFoo() 메서드가 있어야 합니다.
  • 애니메이션화할 속성의 getter (필요한 경우) 및 setter 메서드는 ObjectAnimator에 지정하는 시작 및 끝 값과 동일한 유형에서 작동합니다. 예를 들어 targetObject.setPropName(float)targetObject.getPropName() 다음과 같은 ObjectAnimator를 생성하면 됩니다.
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
    
  • 애니메이션화할 속성이나 객체에 따라 뷰에서 invalidate() 메서드를 호출하여 화면을 강제로 다시 그리도록 해야 할 수 있습니다. 애니메이션 값을 업데이트했습니다. 이 작업은 onAnimationUpdate() 있습니다. 예를 들어, Drawable 객체의 색상 속성을 애니메이션화하면 닫히지 않습니다. View의 모든 속성 setter입니다. 예: setAlpha()setTranslationX() 뷰를 적절히 무효화하므로 이러한 메서드를 호출할 때 뷰를 무효화할 필요가 없습니다. 메서드를 호출할 수 있습니다. 리스너에 대한 자세한 내용은 애니메이션 리스너

AnimatorSet를 사용하여 여러 애니메이션 구성

대부분의 경우 다른 애니메이션이 시작되는 시점 또는 있습니다. Android 시스템에서는 애니메이션을 AnimatorSet로 함께 묶을 수 있으므로 애니메이션 시작 여부를 지정할 수 있습니다. 동시에, 순차적으로 또는 지정된 지연 후에 할 수 있습니다. AnimatorSet 객체를 서로 중첩시킬 수도 있습니다.

다음 코드 스니펫은 다음 Animator를 재생합니다. 객체를 다음과 같은 방식으로 처리합니다.

  1. bounceAnim를 재생합니다.
  2. squashAnim1, squashAnim2, stretchAnim1, 재생 동시에 stretchAnim2입니다.
  3. bounceBackAnim를 재생합니다.
  4. fadeAnim를 재생합니다.

Kotlin

val bouncer = AnimatorSet().apply {
    play(bounceAnim).before(squashAnim1)
    play(squashAnim1).with(squashAnim2)
    play(squashAnim1).with(stretchAnim1)
    play(squashAnim1).with(stretchAnim2)
    play(bounceBackAnim).after(stretchAnim2)
}
val fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
}
AnimatorSet().apply {
    play(bouncer).before(fadeAnim)
    start()
}

자바

AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();

애니메이션 리스너

아래에 설명된 리스너를 사용하여 애니메이션 기간 동안 중요한 이벤트를 수신 대기할 수 있습니다.

  • Animator.AnimatorListener
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate() - 애니메이션의 모든 프레임에서 호출됩니다. 이 이벤트 수신 대상 ValueAnimator 에 의해 생성된 계산된 값을 애니메이션을 적용할 수 있습니다. 값을 사용하려면 ValueAnimator 객체를 쿼리합니다. 이벤트에 전달되어 getAnimatedValue() 메서드로 애니메이션된 현재 값을 가져옵니다. 이를 구현하기 ValueAnimator를 사용하는 경우 리스너가 필요합니다.

      애니메이션화할 속성이나 객체에 따라 뷰에서 invalidate()를 호출하여 새로운 애니메이션 값으로 다시 그리세요. 예를 들어, 드로어블 객체의 색상 속성으로 인해 해당 객체가 있을 때만 화면이 업데이트됩니다. 스스로 다시 그립니다. View의 모든 속성 setter setAlpha()setTranslationX()가 뷰를 무효화함 새 값으로 이 메서드를 호출할 때 뷰를 무효화할 필요가 없습니다.

AnimatorListenerAdapter 클래스를 확장하는 대신 Animator.AnimatorListener 인터페이스를 구현하지 않습니다. Animator.AnimatorListener의 모든 메서드를 구현하려고 함 인터페이스에 추가되었습니다. AnimatorListenerAdapter 클래스는 재정의하도록 선택할 수 있는 메서드의 구현을 제공합니다.

예를 들어 다음 코드 스니펫은 AnimatorListenerAdapter를 만듭니다. onAnimationEnd() 콜백을 사용합니다.

Kotlin

ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            balls.remove((animation as ObjectAnimator).target)
        }
    })
}

자바

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}

ViewGroup 객체의 레이아웃 변경사항 애니메이션화

속성 애니메이션 시스템은 ViewGroup 객체의 변경사항을 애니메이션 처리하는 기능을 제공합니다. View 객체 자체에 애니메이션을 적용하는 쉬운 방법도 제공합니다.

다음 명령어로 ViewGroup 내의 레이아웃 변경사항을 애니메이션으로 표시할 수 있습니다. LayoutTransition 클래스. ViewGroup 내부의 뷰는 애니메이션을 추가하거나 사라지는 애니메이션을 ViewGroup에서 삭제하거나 뷰의 setVisibility() 메서드를 다음과 같이 바꿉니다. VISIBLE, INVISIBLE 또는 GONE입니다. ViewGroup의 나머지 뷰는 뷰를 추가하거나 제거하면 새 위치로 애니메이션 처리됩니다. 사용자는 LayoutTransition 객체의 다음 애니메이션 setAnimator() 호출 다음 중 하나와 함께 Animator 객체를 전달하여 다음 LayoutTransition 상수를 포함합니다.

  • APPEARING - 다음과 같은 항목에서 실행되는 애니메이션을 나타내는 플래그 컨테이너 내에 표시됩니다
  • CHANGE_APPEARING - 다음과 같은 항목에서 실행되는 애니메이션을 나타내는 플래그 변경되는 경우가 많습니다.
  • DISAPPEARING - 다음과 같은 항목에서 실행되는 애니메이션을 나타내는 플래그 컨테이너에서 사라집니다
  • CHANGE_DISAPPEARING - 다음과 같은 항목에서 실행되는 애니메이션을 나타내는 플래그 컨테이너에서 항목이 사라지기 때문에 변경될 수 있습니다

4가지 이벤트 유형에 대한 자체 맞춤 애니메이션을 정의하여 모양을 맞춤설정할 수 있습니다. 또는 애니메이션 시스템에 기본 애니메이션을 사용하도록 지시할 수도 있습니다.

android:animateLayoutchanges 속성을 true로 설정하는 방법은 다음과 같습니다. ViewGroup은 다음을 실행합니다.

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />

이 속성을 true로 설정하면 ViewGroup 및 ViewGroup의 나머지 View

StateListAnimator를 사용하여 보기 상태 변경 애니메이션화

StateListAnimator 클래스를 사용하면 다음과 같은 경우에 실행되는 애니메이터를 정의할 수 있습니다. 뷰의 상태가 변경됩니다. 이 객체는 Animator 객체로, 지정될 때마다 해당 애니메이션을 호출합니다. 뷰 상태 (예: '눌러진' 또는 '포커스가 설정됨')가 변경될 때 발생합니다.

StateListAnimator는 루트가 있는 XML 리소스에서 정의할 수 있습니다. 각각 지정하는 <selector> 요소 및 하위 <item> 요소 StateListAnimator 클래스가 정의한 다른 뷰 상태입니다. 각 <item>에는 속성 애니메이션 집합의 정의가 포함되어 있습니다.

예를 들어 다음 파일은 x 및 y 배율을 변경하는 상태 목록 애니메이터를 만듭니다. 다음과 같습니다.

res/xml/animate_scale.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- the pressed state; increase x and y size to 150% -->
    <item android:state_pressed="true">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
        </set>
    </item>
    <!-- the default, non-pressed state; set x and y size to 100% -->
    <item android:state_pressed="false">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
        </set>
    </item>
</selector>

상태 목록 애니메이터를 보기에 연결하려면 android:stateListAnimator 속성을 다음과 같이 바꿉니다.

<Button android:stateListAnimator="@xml/animate_scale"
        ... />

이제 animate_scale.xml에 정의된 애니메이션이 이 버튼의 상태를 변경할 수 있습니다

또는 대신 상태 목록 애니메이터를 코드의 뷰에 할당하려면 AnimatorInflater.loadStateListAnimator() 메서드를 호출하고 애니메이터를 뷰(View.setStateListAnimator() 메서드 사용)

또는 뷰의 속성을 애니메이션화하는 대신 다음 두 지점 사이에 드로어블 애니메이션을 재생할 수 있습니다. AnimatedStateListDrawable를 사용하여 상태를 변경할 수 있습니다. 일부 시스템 위젯은 Android 5.0에서는 이러한 애니메이션을 기본적으로 사용합니다. 다음 예는 AnimatedStateListDrawable를 XML 리소스로 정의합니다.

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    <item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>

    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>

TypeEvaluator 사용

Android 시스템에서 알 수 없는 유형에 애니메이션을 적용하고 싶다면 자체 TypeEvaluator 인터페이스를 구현하여 평가자의 역할을 합니다. 사용자가 int, float 또는 색상이라는 것으로 알려져 있으며, IntEvaluator, FloatEvaluator, ArgbEvaluator 유형에서 지원됨 있습니다.

TypeEvaluator에서 구현할 메서드가 하나뿐임 인터페이스, evaluate() 메서드 이렇게 하면 애니메이션 속성에 대해 적절한 값을 반환하는 데 사용하는 애니메이터를 애니메이션의 현재 지점을 나타냅니다. FloatEvaluator 클래스는 다음을 보여줍니다. 방법:

Kotlin

private class FloatEvaluator : TypeEvaluator<Any> {

    override fun evaluate(fraction: Float, startValue: Any, endValue: Any): Any {
        return (startValue as Number).toFloat().let { startFloat ->
            startFloat + fraction * ((endValue as Number).toFloat() - startFloat)
        }
    }

}

자바

public class FloatEvaluator implements TypeEvaluator {

    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}

참고: ValueAnimator (또는 ObjectAnimator)가 실행되면 현재 경과된 비율을 계산합니다. 애니메이션 (0과 1 사이의 값)을 생성하고 이에 따라 보간된 버전을 보간기를 사용해야 합니다. 보간된 비율은 TypeEvaluatorfraction 매개변수를 통해 수신하는 것이므로 다음을 실행합니다. 애니메이션 값을 계산할 때 보간기를 고려할 필요가 없습니다.

보간 사용

보간기는 애니메이션의 특정 값이 있습니다. 예를 들어 전체 애니메이션에서 선형으로 발생하도록 지정할 수 있습니다. 즉, 애니메이션이 전체 시간 동안 균일하게 움직이거나 비선형 시간(예: 시작 또는 끝부분에 가속 또는 감속 사용) 애니메이션을 적용할 수 있습니다.

애니메이션 시스템의 보간은 애니메이션의 경과 시간입니다. 보간기는 이 비율을 제공하는 것을 목표로 하는 애니메이션입니다. Android 시스템은 일반적인 보간기 세트를 android.view.animation package 이 중 어느 것도 TimeInterpolator 인터페이스를 구현하고 있습니다.

예를 들어 기본 AccelerateDecelerateInterpolatorLinearInterpolator에서 보간된 비율을 계산하는 방법은 아래 비교되어 있습니다. LinearInterpolator는 경과된 비율에 영향을 주지 않습니다. AccelerateDecelerateInterpolator가 애니메이션으로 가속화되고 감속합니다. 다음 메서드를 통해서는 이러한 보간의 로직을 정의합니다.

AccelerateDecelerateInterpolator

Kotlin

override fun getInterpolation(input: Float): Float =
        (Math.cos((input + 1) * Math.PI) / 2.0f).toFloat() + 0.5f

자바

@Override
public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

LinearInterpolator

Kotlin

override fun getInterpolation(input: Float): Float = input

자바

@Override
public float getInterpolation(float input) {
    return input;
}

다음 표는 이러한 계산을 통해 계산되는 근사치를 나타냅니다. 보간기를 사용해야 합니다.

ms 경과됨 경과된 비율/보간된 비율(선형) 보간된 비율(가속 또는 감속)
0 0 0
200 .2 .1
400 .4 .345
600 .6 .8
800 .8 .9
1000 1 1

표에 표시된 것처럼 LinearInterpolator는 값을 변경합니다. 동일한 속도로, 통과하는 200ms마다 0.2입니다 AccelerateDecelerateInterpolator는 200ms~600ms에서는 LinearInterpolator보다 빠르게 값을 변경하고 600ms~600ms에서는 느리게 값을 변경합니다. 1000ms

키프레임 지정

Keyframe 객체는 시간/값 쌍으로 구성되며, 이를 통해 애니메이션의 특정 시간에 특정 상태를 처리합니다. 각 키프레임에는 자체 보간기를 사용하여 이전 보간의 간격에서 애니메이션의 동작을 이 키프레임의 시간이 포함됩니다.

Keyframe 객체를 인스턴스화하려면 팩토리 중 하나를 사용해야 합니다. 메서드, ofInt(), ofFloat() 또는 ofObject()를 사용하여 적절한 유형의 Keyframe를 가져옵니다. 그런 다음 ofKeyframe() 팩토리 메서드를 사용하여 PropertyValuesHolder 객체를 가져옵니다. 객체를 가져온 후에는 PropertyValuesHolder 객체를 전달하여 애니메이터를 가져오고 애니메이션을 적용할 객체입니다. 다음 코드 스니펫에서는 이 작업 방법을 보여줍니다.

Kotlin

val kf0 = Keyframe.ofFloat(0f, 0f)
val kf1 = Keyframe.ofFloat(.5f, 360f)
val kf2 = Keyframe.ofFloat(1f, 0f)
val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2)
ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation).apply {
    duration = 5000
}

자바

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
rotationAnim.setDuration(5000);

뷰 애니메이션 처리

속성 애니메이션 시스템을 사용하면 View 객체 및 혜택의 간소화된 애니메이션을 만들 수 있습니다. 몇 가지 장점이 있습니다. 뷰 애니메이션 시스템에서 그리기 방식을 변경하여 View 객체를 변형시켰습니다. 이전 가격 각 View의 컨테이너에서 처리됩니다. View 자체에는 조작할 속성이 없기 때문입니다. 따라서 View는 애니메이션으로 보여주지만 View 객체 자체는 변경되지 않습니다. 이 객체가 이전 위치에 남아있음에도 불구하고 화면의 다른 위치에 그려집니다. Android 3.0에서는 새 속성과 이에 상응하는 이러한 단점을 제거하기 위해 getter 및 setter 메서드를 추가했습니다.

속성 애니메이션 시스템 View 객체의 실제 속성을 변경하여 화면의 뷰에 애니메이션을 적용할 수 있습니다. 포함 또한 뷰는 자동으로 invalidate()를 호출합니다. 메서드를 사용하여 속성이 변경될 때마다 화면을 새로고침합니다. 속성 애니메이션을 용이하게 하는 View 클래스의 새 속성은 다음과 같습니다.

  • translationXtranslationY: 이 속성은 뷰가 레이아웃에 의해 설정되는 왼쪽 및 상단 좌표로부터 델타로 위치합니다. 있습니다
  • rotation, rotationX, rotationY: 이러한 속성 피벗 지점을 중심으로 2D (rotation 속성) 및 3D로 회전을 제어합니다.
  • scaleXscaleY: 이 속성은 피벗 지점을 중심으로 보기
  • pivotXpivotY: 이 속성은 회전 및 크기 조정 변환이 발생하는 피벗 지점입니다. 기본적으로 피벗은 점이 객체의 중심에 있습니다.
  • xy: 이 속성은 API를 설명하는 간단한 유틸리티 속성으로 컨테이너 내 뷰의 최종 위치(왼쪽 상단 값과 상단 값 합계의 값) TranslationX 값과 TranslationY 값이 있습니다.
  • alpha: View의 알파 투명도를 나타냅니다. 이 값은 1 (불투명)입니다. 기본적으로 값 0은 완전 투명 (표시되지 않음)을 나타냅니다.

View 객체의 속성(예: 색상 또는 회전 값)에 애니메이션을 적용하려면 속성 애니메이터를 만들고 이 뷰를 있습니다. 예를 들면 다음과 같습니다.

Kotlin

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f)

자바

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

애니메이터 만들기에 대한 자세한 내용은 애니메이터를 사용하여 애니메이션 만들기 섹션을 참조하세요. ValueAnimatorObjectAnimator

ViewPropertyAnimator를 사용하여 애니메이션화

ViewPropertyAnimator는 여러 애니메이션에 애니메이션을 적용하는 간단한 방법을 제공합니다. 단일 기본 Animator를 사용하여 동시에 View의 속성 객체를 지정합니다. 이 메서드는 ObjectAnimator와 매우 유사하게 동작합니다. 이는 뷰 속성의 실제 값을 가져오지만 합니다. 또한 ViewPropertyAnimator를 사용하기 위한 코드는 더 간결하고 읽기 쉽습니다. 다음 코드 스니펫은 ObjectAnimator 객체, 단일 ObjectAnimator, ViewPropertyAnimator(다음 경우) 뷰의 xy 속성에 동시에 애니메이션을 적용합니다.

여러 ObjectAnimator 객체

Kotlin

val animX = ObjectAnimator.ofFloat(myView, "x", 50f)
val animY = ObjectAnimator.ofFloat(myView, "y", 100f)
AnimatorSet().apply {
    playTogether(animX, animY)
    start()
}

자바

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

하나의 ObjectAnimator

Kotlin

val pvhX = PropertyValuesHolder.ofFloat("x", 50f)
val pvhY = PropertyValuesHolder.ofFloat("y", 100f)
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start()

자바

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();

ViewPropertyAnimator

Kotlin

myView.animate().x(50f).y(100f)

자바

myView.animate().x(50f).y(100f);

ViewPropertyAnimator에 관한 자세한 내용은 상응하는 Android 개발자를 참고하세요. 블로그 게시물을 참고하세요.

XML로 애니메이션 선언

속성 애니메이션 시스템을 사용하면 XML을 사용하는 대신 속성 애니메이션을 선언할 수 있습니다. 설정할 수 있습니다 XML로 애니메이션을 정의하면 애니메이션을 쉽게 재사용할 수 있습니다. 애니메이션 순서를 더 쉽게 편집할 수 있습니다.

새 속성 애니메이션 API를 사용하는 애니메이션 파일과 기존 뷰 애니메이션 프레임워크 Android 3.1부터는 속성 애니메이션의 XML 파일을 res/animator/ 디렉터리에 저장해야 합니다.

다음 속성 애니메이션 클래스에는 다음 XML 태그:

XML 선언에서 사용할 수 있는 속성을 찾으려면 애니메이션을 참조하세요. 리소스를 참조하세요. 다음 예에서는 객체 애니메이션의 두 집합을 재생합니다. 순차적으로, 첫 번째 중첩 세트는 두 객체 애니메이션을 함께 재생합니다.

<set android:ordering="sequentially">
    <set>
        <objectAnimator
            android:propertyName="x"
            android:duration="500"
            android:valueTo="400"
            android:valueType="intType"/>
        <objectAnimator
            android:propertyName="y"
            android:duration="500"
            android:valueTo="300"
            android:valueType="intType"/>
    </set>
    <objectAnimator
        android:propertyName="alpha"
        android:duration="500"
        android:valueTo="1f"/>
</set>

이 애니메이션을 실행하려면 코드의 XML 리소스를 AnimatorSet 객체로 확장한 다음 애니메이션 집합을 시작하기 전에 모든 애니메이션의 타겟 객체를 설정해야 합니다. setTarget()을 호출하면 편의상 AnimatorSet의 모든 하위 요소의 단일 타겟 객체가 설정됩니다. 다음 코드는 이 작업의 진행 방법을 보여줍니다.

Kotlin

(AnimatorInflater.loadAnimator(myContext, R.animator.property_animator) as AnimatorSet).apply {
    setTarget(myObject)
    start()
}

자바

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.animator.property_animator);
set.setTarget(myObject);
set.start();

다음과 같이 XML에 ValueAnimator을 선언할 수도 있습니다. 다음 예에 나와 있습니다.

<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:valueType="floatType"
    android:valueFrom="0f"
    android:valueTo="-100f" />

코드에서 이전 ValueAnimator를 사용하려면 다음을 실행합니다. 객체를 확장하고 AnimatorUpdateListener, 업데이트된 애니메이션 값을 가져와 뷰 중 하나의 속성에 사용합니다. 다음과 같습니다.

Kotlin

(AnimatorInflater.loadAnimator(this, R.animator.animator) as ValueAnimator).apply {
    addUpdateListener { updatedAnimation ->
        textView.translationX = updatedAnimation.animatedValue as Float
    }

    start()
}

자바

ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this,
        R.animator.animator);
xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

xmlAnimator.start();

속성 애니메이션을 정의하기 위한 XML 구문에 관한 자세한 내용은 애니메이션을 참조하세요. 리소스 를 참고하세요.

UI 성능에 미치는 잠재적 영향

UI를 업데이트하는 애니메이터는 지정할 수 있습니다. 따라서 리소스를 많이 사용하는 애니메이션을 사용하면 앱 성능에 부정적인 영향을 미칠 수 있습니다.

UI에 애니메이션을 적용하는 데 필요한 작업이 애니메이션 단계에 추가됩니다. 살펴봤습니다 애니메이션이 애니메이션의 GPU 렌더링 프로파일링을 사용 설정하고 모니터링할 수 있습니다 자세한 내용은 GPU 렌더링 프로파일링을 참조하세요. 둘러보기를 참고하세요.