Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion app/src/main/java/com/eva/recorderapp/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.navigation.NavHostController
import com.eva.recorderapp.navigation.AppNavHost
import com.eva.ui.R
import com.eva.ui.activity.animateOnExit
import com.eva.ui.theme.RecorderAppTheme
import dagger.hilt.android.AndroidEntryPoint

Expand All @@ -23,12 +24,15 @@ class MainActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
// splash needs to be initiated here
installSplashScreen()
val splash = installSplashScreen()

super.onCreate(savedInstanceState)

// set enable edge to edge normally
enableEdgeToEdge()

// on splash complete again enable edge to edge
splash.animateOnExit(onAnimationEnd = { enableEdgeToEdge() })
// set activity transitions
setTransitions()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.eva.ui.activity

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.view.View
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import androidx.core.animation.doOnEnd
import androidx.core.animation.doOnStart
import androidx.core.splashscreen.SplashScreen

fun SplashScreen.animateOnExit(
screenViewDuration: Long = 200L,
onAnimationStart: () -> Unit = {},
onAnimationEnd: () -> Unit = {}
) {

setOnExitAnimationListener { screenView ->
// do all the animation is a reverse way
val interpolator = AccelerateDecelerateInterpolator()

val iconScaleXAnimation = ObjectAnimator
.ofFloat(screenView.iconView, View.SCALE_X, 1f, 0.5f)
.apply {
this.interpolator = interpolator
this.duration = screenView.iconAnimationDurationMillis
}

val iconScaleYAnimation = ObjectAnimator
.ofFloat(screenView.iconView, View.SCALE_Y, 1f, 0.5f)
.apply {
this.interpolator = interpolator
this.duration = screenView.iconAnimationDurationMillis
}

val iconTranslateYAnimation = ObjectAnimator
.ofFloat(screenView.iconView, View.TRANSLATION_Y, 0.0f, 20.0f)
.apply {
this.interpolator = interpolator
this.duration = screenView.iconAnimationDurationMillis
}

val viewFadeAnimation = ObjectAnimator
.ofFloat(screenView.view, View.ALPHA, 1.0f, .2f)
.apply {
this.interpolator = DecelerateInterpolator()
this.duration = screenViewDuration
}

val viewTranslateAnimation = ObjectAnimator.ofFloat(
screenView.view,
View.TRANSLATION_Y,
0f,
screenView.view.height.toFloat()
).apply {
this.interpolator = AccelerateInterpolator()
this.duration = screenViewDuration
}

val viewAnimatorSet = AnimatorSet().apply {
playTogether(viewFadeAnimation, viewTranslateAnimation)
doOnEnd {
screenView.remove()
onAnimationEnd()
}
}

val iconAnimatorSet = AnimatorSet().apply {
playTogether(
iconScaleXAnimation,
iconScaleYAnimation,
iconTranslateYAnimation
)
doOnEnd { viewAnimatorSet.start() }
doOnStart { onAnimationStart() }

}
iconAnimatorSet.start()
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
package com.eva.feature_onboarding

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.View
import android.view.Window
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.core.animation.doOnEnd
import androidx.core.animation.doOnStart
import androidx.core.splashscreen.SplashScreen
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
Expand All @@ -27,6 +18,7 @@ import com.eva.feature_onboarding.screen.OnBoardingState
import com.eva.feature_onboarding.screen.OnBoardingViewmodel
import com.eva.feature_onboarding.screen.OnboardingScreen
import com.eva.ui.R
import com.eva.ui.activity.animateOnExit
import com.eva.ui.theme.RecorderAppTheme
import com.eva.utils.IntentConstants
import dagger.hilt.android.AndroidEntryPoint
Expand Down Expand Up @@ -72,9 +64,9 @@ class OnBoardingActivity : ComponentActivity() {
try {
val intent = Intent().apply {
setClassName(applicationContext, IntentConstants.MAIN_ACTIVITY)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
applicationContext.startActivity(intent)
startActivity(intent)
// set activity transitions
setTransitions()
// finish onboarding activity
Expand Down Expand Up @@ -102,75 +94,4 @@ class OnBoardingActivity : ComponentActivity() {
)
}
}


private fun SplashScreen.animateOnExit(
onAnimationStart: () -> Unit = {},
onAnimationEnd: () -> Unit = {}
) {
val screenViewDuration = 200L

setOnExitAnimationListener { screenView ->
// do all the animation is a reverse way
val interpolator = AccelerateDecelerateInterpolator()

val iconScaleXAnimation = ObjectAnimator
.ofFloat(screenView.iconView, View.SCALE_X, 1f, 0.5f)
.apply {
this.interpolator = interpolator
this.duration = screenView.iconAnimationDurationMillis
}

val iconScaleYAnimation = ObjectAnimator
.ofFloat(screenView.iconView, View.SCALE_Y, 1f, 0.5f)
.apply {
this.interpolator = interpolator
this.duration = screenView.iconAnimationDurationMillis
}

val iconTranslateYAnimation = ObjectAnimator
.ofFloat(screenView.iconView, View.TRANSLATION_Y, 0.0f, 20.0f)
.apply {
this.interpolator = interpolator
this.duration = screenView.iconAnimationDurationMillis
}

val viewFadeAnimation = ObjectAnimator
.ofFloat(screenView.view, View.ALPHA, 1.0f, .2f)
.apply {
this.interpolator = DecelerateInterpolator()
this.duration = screenViewDuration
}

val viewTranslateAnimation = ObjectAnimator.ofFloat(
screenView.view,
View.TRANSLATION_Y,
0f,
screenView.view.height.toFloat()
).apply {
this.interpolator = AccelerateInterpolator()
this.duration = screenViewDuration
}

val viewAnimatorSet = AnimatorSet().apply {
playTogether(viewFadeAnimation, viewTranslateAnimation)
doOnEnd {
screenView.remove()
onAnimationEnd()
}
}

val iconAnimatorSet = AnimatorSet().apply {
playTogether(
iconScaleXAnimation,
iconScaleYAnimation,
iconTranslateYAnimation
)
doOnEnd { viewAnimatorSet.start() }
doOnStart { onAnimationStart() }

}
iconAnimatorSet.start()
}
}
}