[Android, Kotlin] Back Stack을 활용한 Fragment 뒤로가기 버튼 동작, Fragment 전환 애니메이션
Android

[Android, Kotlin] Back Stack을 활용한 Fragment 뒤로가기 버튼 동작, Fragment 전환 애니메이션

 

간단한 기분 테스트 앱을 만들며 Fragment를 다룰 일이 많았다.

MainActivity 하나만을 두고 Fragment를 통한 화면 구성을 하는 Single Activity 형식으로 구현하면서

더더욱 Fragment를 많이 건드리게 되었다.

Fragment를 다루며 막혔던 부분에 대한 포스팅을 남긴다.

1. Fragment 전환 시 (show 또는 replace) 뒤로가기 버튼을 누르면 이전 Fragment가 아닌 앱이 꺼져버린다.

2. Fragment 전환 시 애니메이션을 넣고싶다.

 

 

1. Solution
Back Stack 활용

 

Fragment는 기본적으로 하나의 Activity에 종속되어 재사용되는 화면의 조각(Fragment)으로,

Fragment를 stack 형식으로 쌓고 back button press 시 스택이 pop 되는 형식으로 사용하기 위해 Fragment를

supportFragmentManager에 add 할 때 다음과 같은 구문을 추가한다.

 

val transaction: FragmentTransaction =
            requireActivity().supportFragmentManager.beginTransaction()
                .setCustomAnimations(R.anim.horizon_enter_front,
                    R.anim.none,
                    R.anim.none,
                    R.anim.horizon_exit_front)
                .add(R.id.fragmentContainer, fragment, tag)
        transaction.addToBackStack(tag).commitAllowingStateLoss() //이것 추가

 

addToBackStack 메소드는 Back Stack에 해당 Fragment를 추가하는 것으로, 백스택을 사용함으로써 뒤로가기 버튼 클릭 시 앱이 종료되는 것이 아닌 back stack의 최상단 fragment가 제거되는 동작을 수행한다.

 

 

2. Solution
전환 애니메이션

 

res 디렉토리에 anim 이라는 Resource Directory를 만들고, 애니메이션 전환과 관련된 translate set을 만든다.

vertical transition은 사용하지 않고, 본 앱에서는 horizon transition만 사용했다.

 

/*none.xml*/
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fromXDelta="0%"
        android:fromYDelta="0%"
        android:toXDelta="0%"
        android:toYDelta="0%"
        />
</set>



/*horizon_enter*/
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
    <translate
        android:duration="300"
        android:fromXDelta="100%"
        android:toXDelta="0%"
        />
</set>



/*horizon_exit*/
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
    <translate
        android:duration="300"
        android:fromXDelta="0%"
        android:toXDelta="100%"
        />
</set>

 

duration : 동작 시간

fromXDelta : 초기 X 좌표 위치

toXDelta : 애니메이션 완료 후 X 좌표 위치

interpolator : 애니메이션 효과

* XDelta의 기준은 화면 좌상단이다. 디스플레이 기준 좌상단은 0%.

horizon_enter를 예로 들면, 화면은 우측에서 좌측으로 이동하며 등장한다.

- fromXDelta(우측) = 100%

- toXDelta(좌측[디스플레이]) = 0%

본 xml 파일을 사용하여 화면을 show / add / replace 할 때 다음 구문을 추가한다.

 

 

val transaction: FragmentTransaction =
            requireActivity().supportFragmentManager.beginTransaction()
                .setCustomAnimations(R.anim.horizon_enter_front, //이것
                    R.anim.none,
                    R.anim.none,
                    R.anim.horizon_exit_front)
                .add(R.id.fragmentContainer, fragment, tag)

 

총 4개의 anim 인자가 들어가는데, 각각 다음과 같다.

setCustomAnimations(

새로 추가될 Fragment 애니메이션,

현재 Fragment 애니메이션,

pop되어 사라질 때 있을 Fragment 애니메이션

pop되어 사라질 때 Fragment 애니메이션)

 

뒤로가기 클릭 시 동작

 

 

github 소스코드 : https://github.com/HunSeongPark/kotlin-simple-test-MVVM

 

GitHub - HunSeongPark/simple-test: Simple Feeling test using MVVM pattern.

Simple Feeling test using MVVM pattern. Contribute to HunSeongPark/simple-test development by creating an account on GitHub.

github.com