기본 제공 및 맞춤 뒤로 탐색 예측 애니메이션 지원 추가

이미 앱을 새로운 System Back API로 이전한 경우 뒤로 탐색 예측을 선택하여 인앱 애니메이션을 자동으로 수신하고 맞춤 전환도 지원할 수 있습니다.

내장된 인앱 애니메이션 지원 추가

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

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

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

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

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

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

뒤로 탐색 예측 지원 자세히 알아보기

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

Progress API와 맞춤 교차 활동 애니메이션 메서드 overrideActivityTransition을 사용하여 맞춤 인앱 속성 애니메이션과 전환을 만들 수 있습니다.

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

AndroidX Activity 1.8.0-alpha01 이상에서는 Predictive Back 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 전환에서는 지원되지만 프레임워크 전환에서는 지원되지 않습니다. 프레임워크 전환에서 이전하는 것이 좋습니다.
  • 뒤로 탐색 예측 전환은 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의 나가기 애니메이션입니다.