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

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

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

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

전환 클래스 확장

맞춤 전환을 만들려면 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? {}

}

Java

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) 함수를 구현합니다. 프레임워크는 시작 장면에 있는 모든 보기에 사용하도록 이 함수를 호출합니다. 함수 인수는 뷰 참조와 원하는 뷰 값을 저장할 수 있는 Map 인스턴스가 포함된 TransitionValues 객체입니다. 구현에서 이러한 속성 값을 가져온 후 지도에 저장하여 프레임워크에 다시 전달합니다.

속성 값의 키가 다른 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
    }

    ...

}

Java

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)
}

Java

@Override
public void captureEndValues(TransitionValues transitionValues) {
    captureValues(transitionValues);
}

이 예시에서 captureStartValues() 함수와 captureEndValues() 함수 모두 captureValues()를 호출하여 값을 검색하고 저장합니다. captureValues()가 검색하는 뷰 속성은 동일하지만 시작 장면과 종료 장면의 값은 다릅니다. 프레임워크는 뷰의 시작 상태와 종료 상태에 관한 별도의 맵을 유지합니다.

맞춤 애니메이터 만들기

시작 장면의 상태와 종료 장면의 상태 사이의 뷰 변경사항을 애니메이션으로 처리하려면 createAnimator() 함수를 재정의하여 애니메이터를 제공하세요. 프레임워크에서 이 함수를 호출하면 장면 루트 뷰와 개발자가 캡처한 시작 값과 종료 값이 포함된 TransitionValues 객체를 전달합니다.

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

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

시작 장면과 종료 장면에 모두 있는 타겟 뷰의 경우 프레임워크는 startValuesendValues 인수 둘 다에 TransitionValues 객체를 제공합니다. 시작 장면이나 종료 장면에만 있는 타겟 뷰의 경우 프레임워크는 상응하는 인수에 TransitionValues 객체, 다른 인수에 null 객체를 제공합니다.

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

맞춤 전환 적용

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