일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- android
- 병렬프로그래밍
- 코루틴
- 코틀린
- 디자인패턴
- 병럴프로그래밍
- Rxjava
- Compose
- 스레드
- g 단위테스트
- viewmodel
- kotlin강좌
- 책
- 알고리즘
- Gradle
- mockito
- 안드로이드
- k8s
- theming
- 알게되는
- 자바
- ReactiveProgramming
- 커스텀상태
- Kotlin
- 테스트
- Coroutine
- 안드로이드스튜디오
- 안드로이드강좌
- 글또
- 회고
- Today
- Total
선생님, 개발을 잘하고 싶어요.
[잡학] Activity 전환 애니메이션 설정하기, overridePendingTransition 본문
문제 상황
애플리케이션에서 화면 전환은 엄청 중요하죠. 이렇게 중요한 화면 전환, 좀 더 이쁘고 의도에 맞게 하는 방법 없을까요?🤔 애니메이션과 BaseActivity 구현체를 사용해서 간단하게 구현해 봅시다.
overridePendingTransition
간단히 이 함수 하나만 있으면 화면 전환간 애니메이션을 실행할 수 있습니다.
overridePendingTransition(R.anim.none, R.anim.horizon_exit)
이 함수는 두개의 애니메이션 리소스를 함수 인자를 받는데요.
첫 번째 인자는, 새로 나타나는 화면이 취해야 하는 애니메이션
두 번째 인자는, 지금 화면이 취하는 애니메이션입니다.
위의 함수 콜은, 새로 나타는 화면은 가만히, 지금 화면은 오른쪽에서 왼쪽으로 슬라이딩하면서 퇴장하게 하는 코드입니다.
애니메이션 xml
자, 화면에 적용할 애니메이션을 추가해봅시다.
<!-- horizon_enter.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@integer/screen_in_time"
android:fromXDelta="-100%"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toXDelta="0%" />
</set>
왼쪽에서 오른쪽으로 슬라이드 하면서 들어오는 애니메이션 코드입니다.
android:fromXDelta="-100%" -> 디바이스 스크린 왼쪽 부터
android:fromYDelta="0%" -> 디바이스 스크린에 꽉 차는 형태로
이동한다는 의미입니다.
같은 원리로 위아래, 좌 우로 슬라이딩하는 애니메이션 코드를 만들어낼 수 있겠죠?
<!-- horizon_exit.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@integer/screen_out_time"
android:fromXDelta="0%"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toXDelta="-100%" />
</set>
<!-- vertical_enter.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@integer/screen_in_time"
android:fromYDelta="100%"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toYDelta="0%" />
</set>
<!-- vertical_exit.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@integer/screen_out_time"
android:fromYDelta="0%"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toYDelta="100%" />
</set>
아 그리고, 아무것도 안 하는 애니메이션 지정을 위한 애니메이션도 추가해 줍니다.
공식 문서 상에서 overridePendingTransition의 인자로 0을 주면 아무런 애니메이션을 안 한다고 되어 있지만, 실제로는 검은 화면이 됩니다. 이상하죠?
<!-- none.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@integer/screen_in_time"
android:fromXDelta="0%"
android:fromYDelta="0%"
android:toXDelta="0%"
android:toYDelta="0%" />
</set>
overridePendingTransition 호출 위치
애니메이션 준비는 끝났으니, 함수를 호출합시다.
함수 호출은
Activity의 onCreate에서, 이 화면이 켜질 때 동작할 애니메이션을,
finish, onBackPressed에서, 화면이 꺼질 때 동작할 애니메이션을 지정해주면 됩니다.
볼까요?
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 이 화면은, 왼쪽에서 오른쪽으로 슬라이딩 하면서 켜집니다.
overridePendingTransition(R.anim.horizon_enter, R.anim.none)
}
fun someFunction() {
finish()
// 이 화면은, 오른쪽에서 왼쪽으로 슬라이딩 하면서 사라집니다.
overridePendingTransition(R.anim.none, R.anim.horizon_exit)
}
override fun onBackPressed() {
super.onBackPressed()
if (isFinishing) {
// back 버튼으로 화면 종료가 야기되면 동작한다.
overridePendingTransition(R.anim.none, R.anim.horizon_exit)
}
}
반드시 finish 이후에 불러야 한다는 점을 명심해주세요!
애플리케이션에 일괄 적용하기
모든 화면을 종료할 때, 이런 작업을 하는 건 귀찮은 일입니다. 앱 전체적으로 쉽게 화면 전환을 지정할 수 없을까요? 🤔
저는 상속을 사용해서 문제를 해결해 보았습니다.
모든 화면이 상속받는 BaseActivity 만들기
기존 Activity를 보시면, AppCompatActivity클래스를 상속받은 것을 확인할 수 있습니다.
제일 처음 하실 일은, 우리만의 부모 BaseActivity 클래스를 만드는 것입니다.
abstract class BaseActivity(
private val transitionMode: TransitionMode = TransitionMode.NONE
) : AppCompatActivity() {
enum class TransitionMode {
NONE,
HORIZON,
VERTICAL
}
}
해당 화면이 어떤 형태로 켜지는 화면인지 정의하는 enum class를 정의했습니다.
NONE을 지정하면 시스템 기본으로
HORIZON을 지정하면 화면이 좌우로 슬라이딩되며 in / out 되게
VERTICAL로 지정하면 화면이 위아래로 슬라이딩되며 in / out 하는 것을 의도했습니다.
finish, onBackPressed 오버라이드 하기
그리고 부모 클래스의 함수를 오버라이드 해서 overridePendingTransition 호출을 BaseActivity에게 위임합시다.🤗
abstract class BaseActivity(
private val transitionMode: TransitionMode = TransitionMode.NONE
) : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
onInject(savedInstanceState)
super.onCreate(savedInstanceState)
when (transitionMode) {
TransitionMode.HORIZON -> overridePendingTransition(R.anim.horizon_enter, R.anim.none)
TransitionMode.VERTICAL -> overridePendingTransition(R.anim.vertical_enter, R.anim.none)
else -> Unit
}
}
override fun finish() {
super.finish()
when (transitionMode) {
TransitionMode.HORIZON -> overridePendingTransition(R.anim.none, R.anim.horizon_exit)
TransitionMode.VERTICAL -> overridePendingTransition(R.anim.none, R.anim.vertical_exit)
else -> Unit
}
}
override fun onBackPressed() {
super.onBackPressed()
if (isFinishing) {
when (transitionMode) {
TransitionMode.HORIZON -> overridePendingTransition(R.anim.none, R.anim.horizon_exit)
TransitionMode.VERTICAL -> overridePendingTransition(R.anim.none, R.anim.vertical_exit)
else -> Unit
}
}
}
enum class TransitionMode {
NONE,
HORIZON,
VERTICAL
}
}
그리고 실제 화면에서 사용해 볼까요?
// 이미 부모 클래스에게 화면 전환 애니메이션을 위임했습니다.
class ReviewActivity : BaseActivity(TransitionMode.VERTICAL) {
// 아무것도 안하고, 평소 하시던 대로 개발하시면 됩니다.
}
쉽죠?
완료!
다 하셨습니다!
이제 화면 전환 애니메이션에 신경 쓸 필요 없이 애플리케이션 개발이 가능해졌습니다.
디자이너 요구사항이 변경돼서 화면 전환이 변경되어야 한다고요? BaseActivity를 사용해서 앱 전체에 통일된 방법으로 화면 전환 애니메이션을 제공하기 때문에 변화에도 적응하기 쉽습니다. 🤩
'개발 > android 개발' 카테고리의 다른 글
[테스트] MVVM 테스트 하기 - ViewModel 테스트 (0) | 2020.05.24 |
---|---|
[안드로이드 잡학] 앱에 AdMob 추가하기, 실제 코드 적용하기 (0) | 2020.05.10 |
[룸] Android Room 개발, Coroutine과 Test로 편하게 하기. (0) | 2020.04.11 |
[테스트] 코루틴, viewModelScope 를 테스트 하는 방법 (0) | 2020.04.05 |
[테스트] 특정 에러를 던지는 지 테스트 (0) | 2020.03.30 |