Hun's Blog

Start an activity using an animation 본문

Android

Start an activity using an animation

jhk-im 2020. 11. 22. 15:35

developer.android.com/training/transitions/start-activity

 

애니메이션으로 활동 시작  |  Android 개발자  |  Android Developers

머티어리얼 디자인 앱의 활동 전환은 공통 요소 간의 모션 및 변환을 통해 서로 다른 상태 간에 시각적 연결을 제공합니다. 들어가기 및 나가기 전환과 활동 간 공유 요소의 전환을 위한 맞춤 애

developer.android.com

머테리얼 디자인 앱의 액티비티 전환은 공통 elements 사이에서 이동과 transition을 통해 서로다른 상태에서의 시각적 연결을 제공한다. 당신은 `Enter`와 `Exit` transition및 액티비티간 `Shared element`에 대한  커스텀 애니메이션을 지정할 수 있다. 

 

  • `Enter` transition은 액티비티의 뷰가 어떻게 씬으로 들어가는지 결정한다. 
  • `Exit` transition은 액티비티의 뷰가 어떻게 씬에서 빠져나오는지 결정한다. 
  • `Shared element`는 두개의 액티비티에서 공유하는 뷰가 어떻게 transition 되는지를 결정한다. 

안드로이드는 다음과 같이 `Enter`와 `Exit`의 transition을 지원한다. 

  • explode - 씬의 중앙에서 안이나 바깥으로 뷰를 이동시킨다. 
  • slide - 씬의 가장자리에서 안이나 바깥으로 뷰를 이동시킨다. 
  • fade - opacity(불투명도)를 변경하여 뷰를 추가하거나 삭제한다.

Visibility 클래스를 상속받는 모든 transition은 `Enter`혹은 `Exit` 전환으로 지원된다. 

 

안드로이드는 다음과 같은 `Shared elements` transition을 지원한다. 

  • changeBounds - target 뷰의 레이아웃 범위 변경 애니메이션 
  • changeClipBounds - target 뷰의 클립 범위 변경 애니메이션 
  • changeTransform -  target 뷰의 규모와 회전 변경 애니메이션
  • changeImageTransform - target 이미지의 크기와 규모 변경 애니메이션  

앱에서 액티비티 transition을 활성화하면 기본 cross-fading transition이 `Enter`와 `Exit`에서 활성화 된다. 

 

시스템 버전 확인

액티비티 transition API는 Android5.0 (API21)이상에서 사용할 수 있다. 이전 버전과의 호환성을 유지하려면 API를 호출하기 전에

런타임에서 시스템 버전을 확인해야한다. 

// Check if we're running on Android 5.0 or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    // Apply activity transition
} else {
    // Swap without transition
}

 

 

커스텀 transition 지정

먼저 머테리얼 테마의 android:windowActivityTransitions 속성을 사용하여 window content transition을 활성화한다.  또한 `Enter`, `Exit`, `Shared element`에 대한 커스텀 transition을 지정할 수 있다. 

<style name="BaseAppTheme" parent="android:Theme.Material">
  <!-- enable window content transitions -->
  <item name="android:windowActivityTransitions">true</item>

  <!-- specify enter and exit transitions -->
  <item name="android:windowEnterTransition">@transition/explode</item>
  <item name="android:windowExitTransition">@transition/explode</item>

  <!-- specify shared element transitions -->
  <item name="android:windowSharedElementEnterTransition">
    @transition/change_image_transform</item>
  <item name="android:windowSharedElementExitTransition">
    @transition/change_image_transform</item>
</style>

@transition/change_image_transform은 다음과 같이 지정된다. 

<!-- res/transition/change_image_transform.xml -->
<!-- (see also Shared Transitions below) -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
  <changeImageTransform/>
</transitionSet>

<changeImageTransform/> element는 ChangeImageTransfrom 클래스에 해당한다. 

 

*ChangeImageTransform 

해당 클래스는 씬이 변경되기 전후의 ImageView 매트릭스를 캡처하고 transition과정에서 애니메이션을 생성한다.  ChangeBounds와 병합하여  size, shape 및 원활한 애니메이션을 위한 ScaleType을 변경하는 ImageView를 허용한다. 

 

코드에서 transition을 활성화 하려면 Window.requestFeature() 함수를 호출한다. 

// inside your activity (if you did not enable transitions in your theme)
with(window) {
    requestFeature(Window.FEATURE_CONTENT_TRANSITIONS)

    // set an exit transition
    exitTransition = Explode()
}

코드에서 transition을 지정하기 위해 Transition 객체를 사용하여 다음의 함수를 호출한다. 

  • Window.setEnterTransition()
  • Window.setExitTransition()
  • Window.setSharedElementEnterTransition()
  • Window.setSharedElementExitTransition()

Transition의 모든 효과를 보기위해서 호출된 모든 액티비티에 window content transition을 활성화해야한다.

가능한 빨리 `Enter` transition을 시작하려면 Window.setAllowEnterTransitionOverlap() 함수를 사용하여 액티비티를 호출한다. 조금 더 극적인 변화를 가져올 수 있다. 

 

transition을 사용하여 액티비티 시작

transition을 활성화하고 `Exit` transition을 액티비티에 셋팅하면 다음과 같이 다른 액티비트를 호출할 때 transition이 활성화된다. 

startActivity(intent,
              ActivityOptions.makeSceneTransitionAnimation(this).toBundle())

또한 `Enter` transition을 이동할 액티비티에 셋팅하면 액티비티가 시작할 때 transition이 활성화 된다. 

이동할 액티비티에서 transition을 사용하지 않으려면 .toBundle(null)로 제공한다. 

 

 

Shared element로 액티비티 시작

`Shared element`를 가지고 있는 두개의 액티비티 사이에 transition 애니메이션을 만들기 

  • 테마에서 window content transitions 활성화
  • 스타일에 `Shared element` transition 지정 
  • XML 리소스로 transition 정의 
  • android:transitionName 속성을 사용하여 두 레이아웃의 `Shared element`에 공통의 이름 할당
  • ActivityOptions.makeSceneTransitionAnimation() 함수를 사용
// get the element that receives the click event
val imgContainerView = findViewById<View>(R.id.img_container)

// get the common element for the transition in this activity
val androidRobotView = findViewById<View>(R.id.image_small)

// define a click listener
imgContainerView.setOnClickListener( {
    val intent = Intent(this, Activity2::class.java)
    // create the transition animation - the images in the layouts
    // of both activities are defined with android:transitionName="robot"
    val options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot")
    // start the new activity
    startActivity(intent, options.toBundle())
})

코드에서는 View.setTransitionName() 함수를 사용하여 두 액티비티 간의 `Shared element` 이름을 지정할 수 있다.

두번째 액티비티가 종료될 때 transition 애니메이션을 되돌리려면 Activity.finish() 대신 Activity.finishAfterTransition() 함수를 사용한다. 

 

Multiple Shared element로 액티비티 시작

하나 이상의 `Shared element`가 있는 액티비티 transition 애니메이션을 만들려면 android:transitionName 혹은 View.setTransitionName() 함수를 사용하여 각각의 이름을 지정하고 다음과 같이 ActivityOptions 객체를 사용하여 option을 정의한다. 

// Rename the Pair class from the Android framework to avoid a name clash
import android.util.Pair as UtilPair
...
val options = ActivityOptions.makeSceneTransitionAnimation(this,
        UtilPair.create(view1, "agreedName1"),
        UtilPair.create(view2, "agreedName2"))