뒤로 탐색 예측 애니메이션 지원 추가

System Back API를 사용하면 인앱 애니메이션을 수신하고 맞춤 전환을 지원하도록 선택할 수 있습니다.

동영상 1: 뒤로 탐색 예측 애니메이션

선택 후에는 앱에 홈으로 돌아가기, 교차 활동 및 교차 작업을 위한 애니메이션이 표시됩니다.

Material 구성요소 종속 항목을 MDC Android v1.10.0으로 업그레이드하여 다음과 같은 Material 구성요소 애니메이션을 받을 수도 있습니다.

자세한 내용은 GitHub의 Material 구성요소 개발자 안내를 참고하세요.

이 동영상은 Android 설정 앱을 사용하는 교차 활동 및 홈으로의 이동을 위한 뒤로 탐색 예측 애니메이션의 간단한 예를 보여줍니다.

  1. 애니메이션에서 사용자는 뒤로 스와이프하여 이전 설정 화면으로 돌아갑니다(교차 활동 애니메이션의 예).
  2. 이제 이전 화면에서 사용자가 두 번째로 뒤로 스와이프하기 시작하면 배경화면으로 홈 화면의 미리보기가 표시됩니다. 이는 홈으로 돌아가기 애니메이션의 예입니다.
  3. 사용자가 계속해서 오른쪽으로 스와이프하면서 홈 화면의 아이콘으로 축소되는 애니메이션을 보여줍니다.
  4. 이제 사용자가 홈 화면으로 완전히 돌아왔습니다.

뒤로 탐색 예측 동작 지원을 추가하는 방법을 자세히 알아보세요.

맞춤 인앱 전환 및 애니메이션 추가

뒤로 탐색 예측 동작을 사용하여 맞춤 인앱 속성 애니메이션 및 전환, 맞춤 교차 활동 애니메이션, 맞춤 교차 프래그먼트 애니메이션을 만들 수 있습니다.

Progress API를 사용하여 맞춤 전환 추가

AndroidX Activity 1.8.0-alpha01 이상에서는 뒤로 탐색 예측 진행 API를 사용하여 앱의 뒤로 탐색 예측 동작을 위한 맞춤 애니메이션을 개발할 수 있습니다. Progress API는 뷰 애니메이션에 유용하지만 프래그먼트 간의 전환을 애니메이션 처리할 때는 제한사항이 있습니다. OnBackPressedCallback 내에서 사용자가 뒤로 스와이프하는 동안 객체에 애니메이션을 적용하는 handleOnBackProgressed, handleOnBackCancelled, handleOnBackStarted 메서드를 도입했습니다. 시스템에서 제공하는 기본 애니메이션 또는 Material 구성요소 애니메이션보다 더 많이 맞춤설정해야 하는 경우 이 메서드를 사용하세요.

대부분의 앱이 하위 호환 AndroidX API를 사용할 것으로 예상되지만 Android 14 개발자 프리뷰 1 이상에서 테스트할 수 있는 OnBackAnimationCallback 인터페이스 내에도 유사한 플랫폼 API가 있습니다.

AndroidX 전환과 함께 Progress API 사용

Progress API는 Android 14 이상에서 AndroidX 전환 1.5.0-alpha01 이상과 함께 사용하여 뒤로 탐색 예측 전환을 만들 수 있습니다.

  1. beginDelayedTransition 대신 TransitionManager#controlDelayedTransition을 사용하여 사용자가 뒤로 스와이프할 때 전환을 재생합니다.
  2. handleOnBackStarted 내에 전환을 만듭니다.
  3. 사용자가 뒤로 스와이프한 범위를 노출하는 BackEvent.progresscurrentFraction을 연결하여 handleOnBackProgressed 내에서 뒤로 이벤트로 전환을 재생합니다.
  4. 사용자가 handleOnBackPressed에서 뒤로 동작을 커밋한 후 전환을 완료합니다.
  5. 마지막으로 handleOnBackCancelled 내에서 전환 상태를 재설정합니다.

다음 동영상과 Kotlin 코드, XML은 OnBackPressedCallback으로 구현된 두 상자 간의 맞춤 전환을 보여줍니다.

    class MyFragment : Fragment() {

    val transitionSet = TransitionSet().apply {
        addTransition(Fade(Fade.MODE_OUT))
        addTransition(ChangeBounds())
        addTransition(Fade(Fade.MODE_IN))
    }
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val callback = object : OnBackPressedCallback(enabled = false) {

            var controller: TransitionSeekController? = null

            @RequiresApi(34)
            override fun handleOnBackStarted(backEvent: BackEvent) {
                // Create the transition
                controller = TransitionManager.controlDelayedTransition(
                    binding.card,
                    transitionSet
                )
                changeTextVisibility(ShowText.SHORT)
            }

            @RequiresApi(34)
            override fun handleOnBackProgressed(backEvent: BackEvent) {
                // Play the transition as the user swipes back
                if (controller?.isReady == true) {
                    controller?.currentFraction = backEvent.progress
                }
            }

            override fun handleOnBackPressed() {
                // Finish playing the transition when the user commits back
                controller?.animateToEnd()
                this.isEnabled = false
            }

            @RequiresApi(34)
            override fun handleOnBackCancelled() {
                // If the user cancels the back gesture, reset the state
                transition(ShowText.LONG)
            }
        }

        binding.shortText.setOnClickListener {
            transition(ShowText.LONG)
            callback.isEnabled = true
        }

        this.requireActivity().onBackPressedDispatcher.addCallback(callback)
    }

    private fun transition(showText: ShowText) {
        TransitionManager.beginDelayedTransition(
            binding.card,
            transitionSet
        )
        changeTextVisibility(showText)
    }

    enum class ShowText { SHORT, LONG }
    private fun changeTextVisibility(showText: ShowText) {
        when (showText) {
            ShowText.SHORT -> {
                binding.shortText.isVisible = true
                binding.longText.isVisible = false
            }
            ShowText.LONG -> {
                binding.shortText.isVisible = false
                binding.longText.isVisible = true
            }
        }
    }
}
  
<?xml version="1.0" encoding="utf-8"?>
...
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/card"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        ...>

        <TextView
            android:id="@+id/short_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            ... />

        <TextView
            android:id="@+id/long_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"
            .../>

    </androidx.constraintlayout.widget.ConstraintLayout>

뒤로 탐색 예측 전환을 사용할 때는 다음 사항에 유의하세요.

  • isSeekingSupported를 사용하여 전환이 뒤로 탐색 예측을 지원하는지 확인합니다.
  • 맞춤 전환을 위해 true를 반환하도록 isSeekingSupported를 재정의합니다.
  • 애니메이션당 하나의 컨트롤러를 만듭니다.
  • 뒤로 탐색 예측 전환은 AndroidX 전환에서는 지원되지만 프레임워크 전환에서는 지원되지 않습니다. 프레임워크 전환에서 이전하고 대신 Animator 및 AndroidX 전환을 사용하세요.
  • 뒤로 탐색 예측 전환은 Android 14 이상을 실행하는 기기에서 지원되며 이전 버전과 호환되지 않습니다.
  • XML 장면으로 만든 전환도 지원됩니다. handleOnBackStarted에서 TransitionSeekControllercontrolDelayedTransition의 결과 대신 TransitionManager.createSeekController의 결과로 설정합니다.

Android 14 이상에서 맞춤 활동 전환 추가

Android 14 이상에서 맞춤 활동 전환이 뒤로 탐색 예측을 지원하도록 하려면 overridePendingTransition 대신 overrideActivityTransition을 사용하면 됩니다. 즉, 사용자가 뒤로 스와이프하면 전환 애니메이션이 재생됩니다.

작동 방식의 예를 제공하기 위해 백 스택의 활동 A 위에 활동 B가 있는 시나리오를 생각해 보세요. 맞춤 활동 애니메이션은 다음과 같은 방식으로 처리합니다.

  • 활동 B의 onCreate 메서드 내에서 전환 열기 또는 닫기를 호출합니다.
  • 사용자가 활동 B로 이동하면 OVERRIDE_TRANSITION_OPEN을 사용합니다. 사용자가 스와이프하여 활동 A로 다시 이동하는 경우 OVERRIDE_TRANSITION_CLOSE를 사용합니다.
  • OVERRIDE_TRANSITION_CLOSE를 지정하면 enterAnim은 활동 A의 들어가기 애니메이션이고 exitAnim은 활동 B의 나가기 애니메이션입니다.

프래그먼트를 사용한 뒤로 탐색 예측 지원 추가

프래그먼트를 사용한 뒤로 탐색 예측을 구현할 때는 두 가지 접근 방식이 있습니다.

기존 API 사용

기존 API를 사용하는 것이 좋습니다. 이러한 API를 사용하면 화면 가장자리에서 스와이프하여 동작으로 Animator 또는 Androidx 전환을 조작할 수 있습니다. 동작이 기준점을 지나는지에 따라 동작이 완료되어 이전 프래그먼트로 돌아가거나 동작이 취소되어 현재 프래그먼트에 남는지가 결정됩니다. 자세한 내용은 애니메이션을 사용하여 프래그먼트 간 탐색을 참고하세요.

다음 사항에 유의하세요.

  • Transitions 1.5.0 이상 및 Fragments 1.7.0 이상을 가져옵니다. 프래그먼트 내 뒤로 탐색 예측 지원의 대부분은 Transitions 1.5.0 이상에서만 가능한 애니메이션을 검색할 수 있는 Transitions에 의존합니다.
  • FragmentManager 또는 탐색 구성요소와 함께 프래그먼트를 사용하여 백 스택을 처리합니다. 자체 백 스택을 관리하는 경우 뒤로 탐색 예측이 지원되지 않습니다. FragmentManager가 알지 못하는 백 스택에서 이전합니다.
  • 일부 라이브러리에는 뒤로 탐색 예측 지원이 포함되어 있습니다. 문서를 확인해 보세요.
  • Animator 클래스와 AndroidX Transition 라이브러리가 지원됩니다.
  • Animation 클래스와 프레임워크 Transition 라이브러리는 지원되지 않습니다.
  • 예측 애니메이션은 Android 14 이상을 실행하는 기기에서만 작동합니다.

다음 상황에서 뒤로 탐색 예측 교차 프래그먼트를 사용하세요.

일부 Material 모션MaterialFadeThrough, MaterialSharedAxis, MaterialFade를 비롯하여 1.12.02-alpha02 이상부터 뒤로 탐색 예측을 지원합니다. MaterialContainerTransform는 뒤로 탐색 예측을 지원하지 않습니다.

콜백 사용

콜백을 사용하여 교차 프래그먼트 전환을 만들 수 있지만, 콜백을 사용할 때는 사용자가 뒤로 스와이프할 때 이전 프래그먼트를 볼 수 없는 것으로 알려진 제한사항이 있습니다. 뒤로 탐색 예측 설계 가이드에 해당하는 교차 프래그먼트 공유 요소 전환을 만들려면 다음 단계를 따르세요.

OnBackPressedCallback를 만듭니다. handleOnBackProgressed 내에서 프래그먼트를 크기 조정하고 이동합니다. 그런 다음 백 스택에서 팝합니다. 그런 다음 콜백 외부에서 setSharedElementReturnTransition를 사용하여 공유 요소 전환을 실행합니다.

자세한 내용은 GitHub의 코드 샘플을 참고하세요.

요구사항

다음 표를 참고하여 targetSdkVersioncompileSdkVersion, 기기 버전, 종속 항목, 매니페스트 플래그, 프래그먼트 플래그로 제어되는 항목을 알아보세요. 이 표는 코드 요구사항을 나타냅니다.

카테고리 애니메이션 compileSdk targetSdk 기기 버전 android:enableOnBackInvokedCallback 종속 항목
시스템 애니메이션 홈으로 돌아가기 33 모두 35 TRUE 없음
교차 활동 34 모두 35 TRUE 없음
교차 작업 34 모두 35 TRUE 없음
플랫폼 맞춤 교차 활동 34 모두 35 TRUE 없음
Progress API 플랫폼 34 모두 34 TRUE 없음
Material 구성요소 하단 시트 34 모두 34 TRUE Material 구성요소 1.10.0
사이드 시트 34 모두 34 TRUE Material 구성요소 1.10.0
탐색 창 34 모두 34 TRUE Material 구성요소 1.10.0
검색 34 모두 34 TRUE Material 구성요소 1.10.0
Jetpack 애니메이션 맞춤 AndroidX 교차 프래그먼트 34 모두 34 TRUE AndroidX Fragment 1.7
맞춤 AndroidX 전환 34 모두 34 TRUE AndroidX Transition 1.5
Progress API Jetpack 34 모두 34 TRUE AndroidX Activity 1.8

추가 리소스