전환을 사용하여 레이아웃 변경 애니메이션 처리

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

Android의 전환 프레임워크를 사용하면 시작 및 종료 레이아웃을 제공하여 UI에서 모든 종류의 모션을 애니메이션으로 보여줄 수 있습니다. 원하는 애니메이션 유형(예: 뷰 페이드 인 또는 아웃, 뷰 크기 변경)을 선택할 수 있으며 전환 프레임워크에서 시작 레이아웃에서 종료 레이아웃으로 애니메이션하는 방법을 결정합니다.

전환 프레임워크에는 다음 기능이 포함되어 있습니다.

  • 그룹 수준 애니메이션: 뷰 계층 구조의 모든 뷰에 애니메이션 효과를 적용합니다.
  • 내장 애니메이션: 페이드 아웃 또는 이동과 같은 일반적인 효과를 위해 사전 정의된 애니메이션을 사용합니다.
  • 리소스 파일 지원: 레이아웃 리소스 파일에서 뷰 계층 구조 및 내장 애니메이션을 로드합니다.
  • 수명 주기 콜백: 애니메이션과 계층 구조 변경 프로세스 제어 기능을 제공하는 콜백을 수신합니다.

레이아웃 변경을 애니메이션으로 보여주는 샘플 코드는 BasicTransition을 참고하세요.

레이아웃이 다른 레이아웃으로 전환될 때 이를 애니메이션으로 보여주는 기본 프로세스는 다음과 같습니다.

  1. 시작 및 종료 레이아웃의 Scene 객체를 만듭니다. 그러나 시작 레이아웃의 장면은 종종 현재 레이아웃에서 자동으로 결정됩니다.
  2. Transition 객체를 만들어 원하는 애니메이션 유형을 정의합니다.
  3. TransitionManager.go()를 호출하면 시스템에서 애니메이션을 실행하여 레이아웃을 전환합니다.

그림 1의 다이어그램은 레이아웃, 장면, 전환 및 최종 애니메이션 간의 관계를 보여줍니다.

그림 1. 전환 프레임워크에서 애니메이션을 만드는 방법을 보여주는 기본 그림입니다.

장면 만들기

장면에서는 모든 보기와 해당 속성 값을 비롯하여 보기 계층 구조의 상태를 저장합니다. 전환 프레임워크는 시작 장면과 종료 장면 간에 애니메이션을 실행할 수 있습니다.

레이아웃 리소스 파일 또는 코드의 뷰 그룹에서 장면을 만들 수 있습니다. 그러나 전환의 시작 장면은 현재 UI에서 자동으로 결정되는 경우가 많습니다.

장면에서는 장면을 변경할 때 실행하는 고유 작업도 정의할 수 있습니다. 이 기능은 장면으로 전환한 후 뷰 설정을 정리하는 데 유용합니다.

레이아웃 리소스에서 장면 만들기

레이아웃 리소스 파일에서 직접 Scene 인스턴스를 생성할 수 있습니다. 파일의 뷰 계층 구조가 주로 정적이면 이 기법을 사용합니다. 결과 장면은 Scene 인스턴스를 만들 때의 뷰 계층 구조 상태를 나타냅니다. 뷰 계층 구조를 변경한 경우 장면을 다시 만듭니다. 프레임워크는 파일의 전체 뷰 계층 구조에서 장면을 만듭니다. 레이아웃 파일의 일부에서는 장면을 만들 수 없습니다.

레이아웃 리소스 파일에서 Scene 인스턴스를 만들려면 레이아웃에서 장면 루트를 ViewGroup로 검색합니다. 그런 다음 장면의 뷰 계층 구조가 포함된 레이아웃 파일의 리소스 ID와 장면 루트를 사용하여 Scene.getSceneForLayout() 함수를 호출합니다.

장면의 레이아웃 정의

이 섹션의 나머지 부분에 있는 코드 스니펫은 장면 루트 요소가 동일한 두 개의 서로 다른 장면을 만드는 방법을 보여줍니다. 또한 서로 관련되지 않은 여러 Scene 객체를 서로 관련이 있음을 암시하지 않고 로드할 수 있다는 점도 보여줍니다.

이 예는 다음과 같은 레이아웃 정의로 구성됩니다.

  • 텍스트 라벨과 하위 요소 FrameLayout가 있는 활동의 기본 레이아웃
  • 두 개의 텍스트 필드가 있는 첫 번째 장면의 ConstraintLayout
  • 동일한 두 텍스트 필드가 서로 다른 순서로 포함된 두 번째 장면의 ConstraintLayout

이 예는 활동 기본 레이아웃의 하위 레이아웃 내에서 모든 애니메이션이 표시되도록 설계되었습니다. 기본 레이아웃의 텍스트 라벨은 정적으로 유지됩니다.

활동의 기본 레이아웃은 다음과 같이 정의됩니다.

res/layout/activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/master_layout">
    <TextView
        android:id="@+id/title"
        ...
        android:text="Title"/>
    <FrameLayout
        android:id="@+id/scene_root">
        <include layout="@layout/a_scene" />
    </FrameLayout>
</LinearLayout>

이 레이아웃 정의는 텍스트 필드와 장면 루트의 하위 FrameLayout를 포함합니다. 첫 번째 장면의 레이아웃은 기본 레이아웃 파일에 포함됩니다. 프레임워크는 전체 레이아웃 파일만 장면에 로드할 수 있으므로 이렇게 하면 앱이 초기 사용자 인터페이스의 일부로 표시할 뿐만 아니라 장면에 로드할 수도 있습니다.

첫 번째 장면의 레이아웃은 다음과 같이 정의됩니다.

res/layout/a_scene.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    
</androidx.constraintlayout.widget.ConstraintLayout>

두 번째 장면의 레이아웃에는 동일한 ID의 동일한 텍스트 필드가 다른 순서로 배치되어 있습니다. 다음과 같이 정의됩니다.

res/layout/another_scene.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    
</androidx.constraintlayout.widget.ConstraintLayout>

레이아웃에서 장면 생성

두 제약 조건 레이아웃의 정의를 만든 후 각 정의를 위한 장면을 가져올 수 있습니다. 이렇게 하면 두 UI 구성 간에 전환할 수 있습니다. 장면을 가져오려면 장면 루트 및 레이아웃 리소스 ID 참조가 필요합니다.

다음 코드 스니펫은 장면 루트 참조를 가져오고 레이아웃 파일에서 두 개의 Scene 객체를 만드는 방법을 보여줍니다.

Kotlin

val sceneRoot: ViewGroup = findViewById(R.id.scene_root)
val aScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this)
val anotherScene: Scene = Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this)

Java

Scene aScene;
Scene anotherScene;

// Create the scene root for the scenes in this app.
sceneRoot = (ViewGroup) findViewById(R.id.scene_root);

// Create the scenes.
aScene = Scene.getSceneForLayout(sceneRoot, R.layout.a_scene, this);
anotherScene =
    Scene.getSceneForLayout(sceneRoot, R.layout.another_scene, this);

이제 앱에는 뷰 계층 구조에 기반한 두 개의 Scene 객체가 있습니다. 두 장면 모두 res/layout/activity_main.xmlFrameLayout 요소로 정의된 장면 루트를 사용합니다.

코드에 장면 만들기

ViewGroup 객체에서 코드에 Scene 인스턴스를 만들 수도 있습니다. 코드에서 직접 뷰 계층 구조를 수정하거나 동적으로 생성할 때 이 기법을 사용합니다.

코드의 뷰 계층 구조에서 장면을 만들려면 Scene(sceneRoot, viewHierarchy) 생성자를 사용합니다. 이 생성자를 호출하는 것은 레이아웃 파일을 이미 확장했을 때 Scene.getSceneForLayout() 함수를 호출하는 것과 같습니다.

다음 코드 스니펫은 장면 루트 요소와 코드에 있는 장면의 뷰 계층 구조에서 Scene 인스턴스를 만드는 방법을 보여줍니다.

Kotlin

val sceneRoot = someLayoutElement as ViewGroup
val viewHierarchy = someOtherLayoutElement as ViewGroup
val scene: Scene = Scene(sceneRoot, viewHierarchy)

자바

Scene mScene;

// Obtain the scene root element.
sceneRoot = (ViewGroup) someLayoutElement;

// Obtain the view hierarchy to add as a child of
// the scene root when this scene is entered.
viewHierarchy = (ViewGroup) someOtherLayoutElement;

// Create a scene.
mScene = new Scene(sceneRoot, mViewHierarchy);

장면 작업 만들기

프레임워크를 사용하면 장면을 시작하거나 종료할 때 시스템에서 실행하는 맞춤 장면 작업을 정의할 수 있습니다. 프레임워크에서 장면 간의 변경사항을 자동으로 애니메이션 처리하므로 대부분의 경우 맞춤 장면 작업을 정의하지 않아도 됩니다.

장면 작업은 다음과 같은 케이스를 처리하는 데 유용합니다.

  • 동일한 계층 구조에 있지 않은 보기에 애니메이션을 적용할 수 있습니다. 장면 시작 및 종료 작업을 사용하여 시작 장면과 종료 장면의 보기를 애니메이션으로 만들 수 있습니다.
  • ListView 객체와 같이 전환 프레임워크에서 자동으로 애니메이션 처리할 수 없는 뷰에 애니메이션 적용 자세한 내용은 제한사항 섹션을 참고하세요.

맞춤 장면 작업을 제공하려면 작업을 Runnable 객체로 정의하여 Scene.setExitAction() 또는 Scene.setEnterAction() 함수에 전달합니다. 프레임워크는 전환 애니메이션을 실행하기 전 시작 장면에서 setExitAction() 함수를 호출하고 전환 애니메이션을 실행한 후 종료 장면에서 setEnterAction() 함수를 호출합니다.

전환 적용

전환 프레임워크는 Transition 객체를 사용하여 장면 사이의 애니메이션 스타일을 나타냅니다. AutoTransitionFade와 같은 기본 제공 서브클래스를 사용하여 Transition를 인스턴스화하거나 자체 전환을 정의할 수 있습니다. 그런 다음 끝 SceneTransitionTransitionManager.go()에 전달하여 장면 간에 애니메이션을 실행할 수 있습니다.

전환 수명 주기는 활동 수명 주기와 비슷하며, 프레임워크에서 애니메이션 시작과 완료 간에 모니터링하는 전환 상태를 나타냅니다. 중요한 수명 주기 상태에서 프레임워크는 여러 전환 단계에서 사용자 인터페이스를 조정하기 위해 구현할 수 있는 콜백 함수를 호출합니다.

전환 만들기

이전 섹션에서는 다양한 뷰 계층 구조의 상태를 나타내는 장면을 만드는 방법을 보여줍니다. 변경할 시작 장면과 종료 장면을 정의한 후에는 애니메이션을 정의하는 Transition 객체를 만듭니다. 프레임워크를 사용하면 리소스 파일에서 내장형 전환을 지정하고 코드에서 확장하거나 코드에서 직접 내장형 전환 인스턴스를 만들 수 있습니다.

표 1. 내장형 전환 유형.

클래스 태그 결과
AutoTransition <autoTransition/> 기본 전환. 뷰는 페이드 아웃, 이동 및 크기 조절, 페이드 인 순서대로 이루어집니다.
ChangeBounds <changeBounds/> 보기를 이동하고 크기를 조정합니다.
ChangeClipBounds <changeClipBounds/> 장면 변경 전과 후의 View.getClipBounds()를 캡처하고 전환 중에 이러한 변경사항을 애니메이션으로 표시합니다.
ChangeImageTransform <changeImageTransform/> 장면 변경 전후의 ImageView 행렬을 캡처하여 전환 중에 애니메이션을 적용합니다.
ChangeScroll <changeScroll/> 장면 변경 전후에 타겟의 스크롤 속성을 캡처하고 변경사항을 애니메이션으로 표시합니다.
ChangeTransform <changeTransform/> 장면 변경 전후의 뷰 크기 및 회전을 캡처하고 전환 중에 이러한 변경사항을 애니메이션으로 표시합니다.
Explode <explode/> 시작 및 종료 장면에서 타겟 보기의 공개 상태 변경사항을 추적하고 장면을 장면의 가장자리에서 안팎으로 이동합니다.
Fade <fade/> fade_in는 뷰를 페이드 인합니다.
fade_out는 뷰를 페이드 아웃합니다.
fade_in_out (기본값)는 fade_out 다음에 fade_in를 실행합니다.
Slide <slide/> 시작 및 종료 장면에서 타겟 보기의 가시성 변경을 추적하고 장면의 가장자리 중 하나에서 뷰를 안팎으로 이동합니다.

리소스 파일에서 전환 인스턴스 만들기

이 기법을 사용하면 활동 코드를 변경하지 않고도 전환 정의를 수정할 수 있습니다. 이 기법은 여러 전환 지정 섹션에서 설명한 것처럼 복잡한 전환 정의를 애플리케이션 코드에서 분리하는 데도 유용합니다.

리소스 파일에 내장형 전환을 지정하려면 다음 단계를 따르세요.

  • 프로젝트에 res/transition/ 디렉터리를 추가합니다.
  • 이 디렉터리에 새로운 XML 리소스 파일을 만듭니다.
  • 내장형 전환 중 하나의 XML 노드를 추가합니다.

예를 들어 다음 리소스 파일은 Fade 전환을 지정합니다.

res/transition/fade_transition.xml

<fade xmlns:android="http://schemas.android.com/apk/res/android" />

다음 코드 스니펫은 리소스 파일의 활동 내에서 Transition 인스턴스를 확장하는 방법을 보여줍니다.

Kotlin

var fadeTransition: Transition =
    TransitionInflater.from(this)
                      .inflateTransition(R.transition.fade_transition)

Java

Transition fadeTransition =
        TransitionInflater.from(this).
        inflateTransition(R.transition.fade_transition);

개발자의 코드에서 전환 인스턴스 만들기

이 기법은 코드에서 사용자 인터페이스를 수정하는 경우 전환 객체를 동적으로 만들고 매개변수가 거의 또는 전혀 없는 간단한 내장형 전환 인스턴스를 만드는 경우에 유용합니다.

내장형 전환 인스턴스를 만들려면 Transition 클래스의 서브클래스에 있는 공개 생성자 중 하나를 호출합니다. 예를 들어 다음 코드 스니펫은 Fade 전환 인스턴스를 만듭니다.

Kotlin

var fadeTransition: Transition = Fade()

Java

Transition fadeTransition = new Fade();

전환 적용

일반적으로 사용자 작업과 같은 이벤트에 응답하여 여러 뷰 계층 구조 간에 변경하기 위해 전환을 적용합니다. 검색 앱을 예로 들어 보겠습니다. 사용자가 검색어를 입력하고 검색 버튼을 탭하면 검색 버튼을 페이드 아웃하고 검색 결과를 페이드 인하는 전환을 적용하는 동안 앱이 결과 레이아웃을 나타내는 장면으로 변경됩니다.

활동의 이벤트에 응답하여 전환을 적용하는 동안 장면을 변경하려면 다음 스니펫과 같이 애니메이션에 사용할 종료 장면과 전환 인스턴스와 함께 TransitionManager.go() 클래스 함수를 호출합니다.

Kotlin

TransitionManager.go(endingScene, fadeTransition)

Java

TransitionManager.go(endingScene, fadeTransition);

프레임워크는 전환 인스턴스에서 지정한 애니메이션을 실행하는 동안 종료 장면의 뷰 계층 구조로 장면 루트 내의 뷰 계층 구조를 변경합니다. 시작 장면은 마지막 전환의 종료 장면입니다. 이전 전환이 없으면 사용자 인터페이스의 현재 상태에 따라 자동으로 시작 장면이 결정됩니다.

전환 인스턴스를 지정하지 않으면 전환 관리자가 대부분의 상황에 적합한 자동 전환을 적용할 수 있습니다. 자세한 내용은 TransitionManager 클래스의 API 참조를 확인하세요.

특정 타겟 보기 선택

프레임워크는 기본적으로 시작 장면과 종료 장면의 모든 뷰에 전환을 적용합니다. 경우에 따라 장면에 있는 뷰의 하위 집합에만 애니메이션을 적용할 수 있습니다. 프레임워크를 사용하면 애니메이션으로 보여줄 특정 뷰를 선택할 수 있습니다. 예를 들어 프레임워크는 ListView 객체의 변경사항을 애니메이션 처리하는 것을 지원하지 않으므로 전환 중에 변경사항을 애니메이션화하려고 하지 마세요.

전환 중에 애니메이션으로 보여주는 각 보기는 타겟이라고 합니다. 장면과 연결된 뷰 계층 구조의 일부인 타겟만 선택할 수 있습니다.

타겟 목록에서 뷰를 하나 이상 삭제하려면 전환을 시작하기 전에 removeTarget() 메서드를 호출합니다. 개발자가 지정하는 뷰만 타겟 목록에 추가하려면 addTarget() 함수를 호출합니다. 자세한 내용은 Transition 클래스의 API 참조를 확인하세요.

여러 전환 지정

애니메이션의 효과를 극대화하려면 장면 사이에 발생하는 변경 유형에 애니메이션을 일치시킵니다. 예를 들어 일부 뷰를 삭제하고 장면 사이에 다른 뷰를 추가하는 경우 페이드 아웃 또는 페이드 인 애니메이션은 일부 뷰를 더 이상 사용할 수 없음을 눈에 띄게 나타냅니다. 화면의 여러 지점으로 뷰를 이동하는 경우 사용자가 뷰의 새 위치를 알 수 있도록 이동에 애니메이션을 적용하는 것이 좋습니다.

전환 프레임워크를 사용하면 개별 내장 또는 맞춤 전환 그룹이 포함된 전환 세트에 애니메이션 효과를 결합할 수 있으므로 애니메이션을 하나만 선택할 필요는 없습니다.

XML로 된 전환 컬렉션에서 전환 세트를 정의하려면 res/transitions/ 디렉터리에 리소스 파일을 만들고 TransitionSet 요소 아래에 전환을 나열합니다. 예를 들어 다음 스니펫은 AutoTransition 클래스와 동작이 동일한 전환 세트를 지정하는 방법을 보여줍니다.

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:transitionOrdering="sequential">
    <fade android:fadingMode="fade_out" />
    <changeBounds />
    <fade android:fadingMode="fade_in" />
</transitionSet>

전환 세트를 코드의 TransitionSet 객체로 확장하려면 활동에서 TransitionInflater.from() 함수를 호출합니다. TransitionSet 클래스는 Transition 클래스에서 확장되므로 다른 Transition 인스턴스와 마찬가지로 전환 관리자와 함께 사용할 수 있습니다.

장면 없이 전환 적용

뷰 계층 구조를 변경하는 것이 사용자 인터페이스를 수정하는 유일한 방법은 아닙니다. 현재 계층 구조 내에서 하위 뷰를 추가, 수정, 삭제하여 변경할 수도 있습니다.

예를 들어 단일 레이아웃으로 검색 상호작용을 구현할 수 있습니다. 검색 입력란과 검색 아이콘이 표시된 레이아웃으로 시작합니다. 결과를 표시하도록 사용자 인터페이스를 변경하려면 사용자가 검색 버튼을 탭할 때 ViewGroup.removeView() 함수를 호출하여 검색 버튼을 삭제하고 ViewGroup.addView() 함수를 호출하여 검색 결과를 추가합니다.

대안이 거의 동일한 두 개의 계층 구조를 사용하는 경우 이 접근 방식을 사용할 수 있습니다. 사용자 인터페이스의 사소한 차이로 두 개의 개별 레이아웃 파일을 만들고 유지하는 대신 코드에서 수정하는 뷰 계층 구조가 포함된 하나의 레이아웃 파일을 사용할 수 있습니다.

현재 뷰 계층 구조 내에서 이 방식으로 변경하면 장면을 만들지 않아도 됩니다. 대신 지연된 전환을 사용하여 뷰 계층 구조의 두 상태 간에 전환을 만들고 적용할 수 있습니다. 전환 프레임워크의 이 기능은 현재 뷰 계층 구조 상태로 시작하고 뷰의 변경사항을 기록하고 시스템에서 사용자 인터페이스를 다시 그릴 때 변경사항을 애니메이션으로 보여주는 전환을 적용합니다.

단일 뷰 계층 구조 내에 지연된 전환을 만들려면 다음 단계를 따르세요.

  1. 전환을 트리거하는 이벤트가 발생하면 TransitionManager.beginDelayedTransition() 함수를 호출하여 변경하려는 모든 뷰의 상위 뷰와 사용할 전환을 제공합니다. 프레임워크는 하위 뷰의 현재 상태와 속성 값을 저장합니다.
  2. 사용 사례에 맞게 필요한 대로 하위 보기를 변경합니다. 프레임워크는 하위 뷰와 그 속성의 변경사항을 기록합니다.
  3. 시스템에서 변경사항에 따라 사용자 인터페이스를 다시 그릴 때 프레임워크는 원래 상태와 새 상태 간의 변경사항을 애니메이션으로 보여줍니다.

다음 예에서는 지연된 전환을 사용하여 텍스트 뷰를 뷰 계층 구조에 추가하는 과정을 애니메이션으로 보여주는 방법을 보여줍니다. 첫 번째 스니펫은 레이아웃 정의 파일을 보여줍니다.

res/layout/activity_main.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <EditText
        android:id="@+id/inputText"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    ...
</androidx.constraintlayout.widget.ConstraintLayout>

다음 스니펫에서는 텍스트 보기 추가를 애니메이션으로 보여주는 코드를 확인할 수 있습니다.

MainActivity

Kotlin

setContentView(R.layout.activity_main)
val labelText = TextView(this).apply {
    text = "Label"
    id = R.id.text
}
val rootView: ViewGroup = findViewById(R.id.mainLayout)
val mFade: Fade = Fade(Fade.IN)
TransitionManager.beginDelayedTransition(rootView, mFade)
rootView.addView(labelText)

Java

private TextView labelText;
private Fade mFade;
private ViewGroup rootView;
...
// Load the layout.
setContentView(R.layout.activity_main);
...
// Create a new TextView and set some View properties.
labelText = new TextView(this);
labelText.setText("Label");
labelText.setId(R.id.text);

// Get the root view and create a transition.
rootView = (ViewGroup) findViewById(R.id.mainLayout);
mFade = new Fade(Fade.IN);

// Start recording changes to the view hierarchy.
TransitionManager.beginDelayedTransition(rootView, mFade);

// Add the new TextView to the view hierarchy.
rootView.addView(labelText);

// When the system redraws the screen to show this update,
// the framework animates the addition as a fade in.

전환 수명 주기 콜백 정의

전환 수명 주기는 활동 수명 주기와 비슷합니다. TransitionManager.go() 함수 호출과 애니메이션 완료 사이의 기간 동안 프레임워크에서 모니터링하는 전환 상태를 나타냅니다. 중요한 수명 주기 상태에서 프레임워크는 TransitionListener 인터페이스에서 정의된 콜백을 호출합니다.

전환 수명 주기 콜백은 예를 들어 장면을 변경하는 동안 시작 뷰 계층 구조에서 종료 뷰 계층 구조로 뷰 속성 값을 복사하는 데 유용합니다. 종료 뷰 계층 구조는 전환이 완료될 때까지 확장되지 않으므로 시작 뷰에서 종료 뷰 계층 구조의 뷰로 값을 단순히 복사할 수 없습니다. 대신, 변수에 값을 저장한 다음 프레임워크가 전환을 완료하면 종료 뷰 계층 구조에 복사해야 합니다. 전환이 완료될 때 알림을 받으려면 활동에서 TransitionListener.onTransitionEnd() 함수를 구현합니다.

자세한 내용은 TransitionListener 클래스의 API 참조를 확인하세요.

제한사항

이 섹션에는 전환 프레임워크의 몇 가지 알려진 제한사항이 나열되어 있습니다.

  • SurfaceView에 적용된 애니메이션은 올바르게 표시되지 않을 수 있습니다. SurfaceView 인스턴스는 UI가 아닌 스레드에서 업데이트되므로 업데이트가 다른 뷰의 애니메이션과 동기화되지 않을 수 있습니다.
  • 일부 특정 전환 유형은 TextureView에 적용했을 때 원하는 애니메이션 효과를 얻지 못할 수 있습니다.
  • ListView와 같이 AdapterView를 확장하는 클래스는 전환 프레임워크와 호환되지 않는 방식으로 하위 뷰를 관리합니다. AdapterView에 따라 뷰에 애니메이션을 적용하려고 하면 기기 디스플레이가 응답하지 않을 수 있습니다.
  • 애니메이션으로 TextView의 크기를 조절하려고 하면 객체의 크기가 완전히 조절되기 전에 텍스트가 새 위치에 표시됩니다. 이 문제를 방지하려면 텍스트가 포함된 뷰의 크기 조절을 애니메이션 처리하지 마세요.