맞춤 전환 애니메이션 만들기

Compose 사용해 보기
Jetpack Compose는 Android에 권장되는 UI 도구 키트입니다. Compose에서 애니메이션을 추가하는 방법을 알아보세요.

맞춤 전환을 사용하면 내장형 전환 클래스에서 사용할 수 없는 애니메이션을 만들 수 있습니다. 예를 들어 텍스트의 전경색을 회색으로 바꾸어 새 화면에서 필드가 사용되지 않음을 나타내는 맞춤 전환을 정의할 수 있습니다. 이와 같이 변경하면 사용자가 사용 안함으로 설정한 필드를 볼 수 있습니다.

맞춤 전환에서는 내장형 전환 유형 중 하나와 같이 시작 테마와 종료 테마 둘 다의 하위 보기에 애니메이션을 적용합니다. 그러나 내장형 전환 유형과 달리 속성 값을 캡처하고 애니메이션을 생성하는 코드를 제공해야 합니다. 애니메이션에 사용할 타겟 보기의 하위 집합도 정의할 수 있습니다.

이 페이지에서는 속성 값을 캡처하고 애니메이션을 생성하여 맞춤 전환을 만드는 방법을 설명합니다.

전환 클래스 확장

맞춤 전환을 만들려면 Transition 클래스를 확장하는 프로젝트에 클래스를 추가하고 다음 스니펫에 나와 있는 함수를 재정의합니다.

Kotlin자바
class CustomTransition : Transition() {

    override fun captureStartValues(transitionValues: TransitionValues) {}

    override fun captureEndValues(transitionValues: TransitionValues) {}

    override fun createAnimator(
        sceneRoot: ViewGroup,
        startValues: TransitionValues?,
        endValues: TransitionValues?
    ): Animator? {}

}
public class CustomTransition extends Transition {

    @Override
    public void captureStartValues(TransitionValues values) {}

    @Override
    public void captureEndValues(TransitionValues values) {}

    @Override
    public Animator createAnimator(ViewGroup sceneRoot,
                                   TransitionValues startValues,
                                   TransitionValues endValues) {}
}

다음 섹션에서는 이 함수를 재정의하는 방법을 설명합니다.

보기 속성 값 캡처

전환 애니메이션에서는 속성 애니메이션 개요에 설명된 속성 애니메이션 시스템을 사용합니다. 속성 애니메이션은 지정된 기간 동안 보기 속성을 시작 값에서 종료 값으로 변경하므로 프레임워크에 속성의 시작 값과 종료 값이 모두 있어야 애니메이션을 구성할 수 있습니다.

그러나 속성 애니메이션에는 대개 모든 보기의 속성 값 중 적은 수의 하위 집합만 있으면 됩니다. 예를 들어 색상 애니메이션에는 색상 속성 값이 필요한 반면, 이동 애니메이션에는 위치 속성 값이 있어야 합니다. 애니메이션에 필요한 속성 값은 전환별로 다르므로 전환 프레임워크에서 전환에 모든 속성 값을 제공하지는 않습니다. 대신 프레임워크에서는 전환 시 필요한 속성 값만 캡처하여 프레임워크에 저장하는 데 사용할 수 있는 콜백 함수를 호출합니다.

시작 값 캡처

시작 보기 값을 프레임워크에 전달하려면 captureStartValues(transitionValues) 함수를 구현합니다. 프레임워크는 시작 장면에 있는 모든 보기에 사용하도록 이 함수를 호출합니다. 함수 인수는 보기의 참조를 포함하는 TransitionValues 객체 및 원하는 보기 값을 저장할 수 있는 Map 인스턴스입니다. 구현 시 이 속성 값을 검색한 후 맵에 저장하여 프레임워크에 다시 전달합니다.

속성 값의 키가 다른 TransitionValues 키와 충돌하지 않도록 다음과 같은 이름 지정 체계를 사용합니다.

package_name:transition_name:property_name

다음 스니펫에서는 captureStartValues() 함수의 구현을 보여줍니다.

Kotlin자바
class CustomTransition : Transition() {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private val PROPNAME_BACKGROUND = "com.example.android.customtransition:CustomTransition:background"

    override fun captureStartValues(transitionValues: TransitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues)
    }

    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private fun captureValues(transitionValues: TransitionValues) {
        // Get a reference to the view
        val view = transitionValues.view
        // Store its background property in the values map
        transitionValues.values[PROPNAME_BACKGROUND] = view.background
    }

    ...

}
public class CustomTransition extends Transition {

    // Define a key for storing a property value in
    // TransitionValues.values with the syntax
    // package_name:transition_class:property_name to avoid collisions
    private static final String PROPNAME_BACKGROUND =
            "com.example.android.customtransition:CustomTransition:background";

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        // Call the convenience method captureValues
        captureValues(transitionValues);
    }


    // For the view in transitionValues.view, get the values you
    // want and put them in transitionValues.values
    private void captureValues(TransitionValues transitionValues) {
        // Get a reference to the view
        View view = transitionValues.view;
        // Store its background property in the values map
        transitionValues.values.put(PROPNAME_BACKGROUND, view.getBackground());
    }
    ...
}

종료 값 캡처

프레임워크는 종료 장면에 있는 타겟 보기마다 한 번 captureEndValues(TransitionValues) 함수를 호출합니다. captureEndValues()는 다른 모든 면에서 captureStartValues()와 동일하게 작동합니다.

다음 코드 스니펫에서는 captureEndValues() 함수의 구현을 보여줍니다.

Kotlin자바
override fun captureEndValues(transitionValues: TransitionValues) {
    captureValues(transitionValues)
}
@Override
public void captureEndValues(TransitionValues transitionValues) {
    captureValues(transitionValues);
}

이 예에서는 captureStartValues() 함수와 captureEndValues() 함수를 통해 captureValues()를 호출하여 값을 검색하고 저장합니다. captureValues()에서 검색하는 보기 속성은 동일하지만, 시작 장면과 종료 장면의 값은 서로 다릅니다. 프레임워크에서는 뷰의 시작 상태와 종료 상태별로 구분된 맵을 유지 관리합니다.

맞춤 애니메이터 만들기

시작 장면 상태와 종료 장면 상태 사이의 뷰 변경사항을 애니메이션으로 보여주려면 createAnimator() 함수를 재정의하여 애니메이터를 제공합니다. 프레임워크는 이 함수를 호출할 때 캡처된 시작 및 종료 값을 포함하는 TransitionValues 객체와 장면 루트 보기를 전달합니다.

프레임워크가 createAnimator() 함수를 호출하는 횟수는 시작 장면과 종료 장면 사이의 변경에 따라 달라집니다.

예를 들어 맞춤 전환으로 구현된 페이드 아웃 또는 페이드 인 애니메이션을 생각해 보세요. 시작 장면에 5개의 타겟이 있고 이 중 2개가 종료 장면에서 삭제되고 종료 장면에 시작 장면의 3개 타겟과 새 타겟이 있으면 프레임워크는 createAnimator()를 6번 호출합니다. 세 번의 호출은 두 장면 객체에 모두 머무는 타겟의 페이드 아웃 및 페이드 인 애니메이션을 만듭니다. 두 번 더 호출하면 끝 장면에서 삭제된 타겟의 페이드 아웃 애니메이션이 실행됩니다. 한 번 호출하면 종료 장면에서 새 타겟의 페이드 인 애니메이션이 실행됩니다.

시작 장면과 종료 장면 둘 다에 있는 타겟 보기의 경우 프레임워크에서 startValuesendValues 인수 둘 다에 TransitionValues 객체를 제공합니다. 시작 장면 또는 종료 장면에만 있는 타겟 보기의 경우 프레임워크에서 startValues 또는 endValues 인수에 TransitionValues 객체를 제공하고 다른 인수에는 null을 제공합니다.

맞춤 전환을 만들 때 createAnimator(ViewGroup, TransitionValues, TransitionValues) 함수를 구현하려면 캡처한 보기 속성 값을 사용하여 Animator 객체를 만들어 프레임워크에 반환합니다. 구현 예는 CustomTransition 샘플의 ChangeColor 클래스를 참고하세요. 속성 애니메이터에 관한 자세한 내용은 속성 애니메이션을 참고하세요.

맞춤 전환 적용

맞춤 전환은 내장형 전환과 작동 방식이 같습니다. 전환 적용에 설명된 대로 전환 관리자를 사용하여 맞춤 전환을 적용할 수 있습니다.