diff --git a/app/src/main/java/com/eva/recorderapp/MainActivity.kt b/app/src/main/java/com/eva/recorderapp/MainActivity.kt index 50149ac..bce4dee 100644 --- a/app/src/main/java/com/eva/recorderapp/MainActivity.kt +++ b/app/src/main/java/com/eva/recorderapp/MainActivity.kt @@ -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 @@ -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() diff --git a/core/ui/src/main/java/com/eva/ui/activity/SplashExitAnimationExt.kt b/core/ui/src/main/java/com/eva/ui/activity/SplashExitAnimationExt.kt new file mode 100644 index 0000000..cf34098 --- /dev/null +++ b/core/ui/src/main/java/com/eva/ui/activity/SplashExitAnimationExt.kt @@ -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() + } +} \ No newline at end of file diff --git a/feature/onboarding/src/main/java/com/eva/feature_onboarding/OnBoardingActivity.kt b/feature/onboarding/src/main/java/com/eva/feature_onboarding/OnBoardingActivity.kt index be0ede1..6de9572 100644 --- a/feature/onboarding/src/main/java/com/eva/feature_onboarding/OnBoardingActivity.kt +++ b/feature/onboarding/src/main/java/com/eva/feature_onboarding/OnBoardingActivity.kt @@ -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 @@ -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 @@ -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 @@ -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() - } - } } \ No newline at end of file