diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
index a58f930df..4c5f01cd4 100644
--- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
+++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt
@@ -168,7 +168,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
swipeRefresh = WeakReference(swipeRefresh),
arguments = arguments!!
).apply {
- beginAnimationIfNecessary()
+ beginAnimateInIfNecessary()
}
return getSessionById()?.also { session ->
diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserAnimator.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserAnimator.kt
index 5b7e6b019..74c4224db 100644
--- a/app/src/main/java/org/mozilla/fenix/browser/BrowserAnimator.kt
+++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserAnimator.kt
@@ -41,17 +41,34 @@ class BrowserAnimator(
private val unwrappedSwipeRefresh: View?
get() = swipeRefresh.get()
+ private val browserInValueAnimator = ValueAnimator.ofFloat(0f, END_ANIMATOR_VALUE).apply {
+ addUpdateListener {
+ unwrappedSwipeRefresh?.scaleX = STARTING_XY_SCALE + XY_SCALE_MULTIPLIER * it.animatedFraction
+ unwrappedSwipeRefresh?.scaleY = STARTING_XY_SCALE + XY_SCALE_MULTIPLIER * it.animatedFraction
+ unwrappedSwipeRefresh?.alpha = it.animatedFraction
+ }
+
+ doOnEnd {
+ unwrappedEngineView?.asView()?.visibility = View.VISIBLE
+ unwrappedSwipeRefresh?.background = null
+ arguments.putBoolean(SHOULD_ANIMATE_FLAG, false)
+ }
+
+ interpolator = DecelerateInterpolator()
+ duration = ANIMATION_DURATION
+ }
+
/**
- * Triggers the browser animation to run if necessary (based on the SHOULD_ANIMATE_FLAG). Also
+ * Triggers the *in* browser animation to run if necessary (based on the SHOULD_ANIMATE_FLAG). Also
* removes the flag from the bundle so it is not played on future entries into the fragment.
*/
- fun beginAnimationIfNecessary() {
+ fun beginAnimateInIfNecessary() {
val shouldAnimate = arguments.getBoolean(SHOULD_ANIMATE_FLAG, false)
if (shouldAnimate) {
viewLifeCycleScope?.launch(Dispatchers.Main) {
delay(ANIMATION_DELAY)
captureEngineViewAndDrawStatically {
- animateBrowserEngine(unwrappedSwipeRefresh)
+ browserInValueAnimator.start()
}
}
} else {
@@ -62,26 +79,15 @@ class BrowserAnimator(
}
/**
- * Details exactly how the browserEngine animation should look and plays it.
+ * Triggers the *out* browser animation to run.
*/
- private fun animateBrowserEngine(browserEngine: View?) {
- val valueAnimator = ValueAnimator.ofFloat(0f, END_ANIMATOR_VALUE)
-
- valueAnimator.addUpdateListener {
- browserEngine?.scaleX = STARTING_XY_SCALE + XY_SCALE_MULTIPLIER * it.animatedFraction
- browserEngine?.scaleY = STARTING_XY_SCALE + XY_SCALE_MULTIPLIER * it.animatedFraction
- browserEngine?.alpha = it.animatedFraction
+ fun beginAnimateOut() {
+ viewLifeCycleScope?.launch(Dispatchers.Main) {
+ captureEngineViewAndDrawStatically {
+ unwrappedEngineView?.asView()?.visibility = View.GONE
+ browserInValueAnimator.reverse()
+ }
}
-
- valueAnimator.doOnEnd {
- unwrappedEngineView?.asView()?.visibility = View.VISIBLE
- unwrappedSwipeRefresh?.background = null
- arguments.putBoolean(SHOULD_ANIMATE_FLAG, false)
- }
-
- valueAnimator.interpolator = DecelerateInterpolator()
- valueAnimator.duration = ANIMATION_DURATION
- valueAnimator.start()
}
/**
diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt
index ca464be31..074418199 100644
--- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt
+++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarController.kt
@@ -14,6 +14,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.MainScope
+import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
@@ -300,7 +301,11 @@ class DefaultBrowserToolbarController(
}
private fun animateTabAndNavigateHome() {
- browserAnimator.captureEngineViewAndDrawStatically {
+ scope.launch {
+ browserAnimator.beginAnimateOut()
+ // Delay for a short amount of time so the browser has time to start animating out
+ // before we transition the fragment. This makes the animation feel smoother
+ delay(ANIMATION_DELAY)
if (!navController.popBackStack(R.id.homeFragment, false)) {
val directions = BrowserFragmentDirections.actionBrowserFragmentToHomeFragment()
navController.nav(
@@ -356,8 +361,7 @@ class DefaultBrowserToolbarController(
}
companion object {
- @VisibleForTesting
- const val TAB_ITEM_TRANSITION_NAME = "tab_item"
+ const val ANIMATION_DELAY = 50L
internal const val TELEMETRY_BROWSER_IDENTIFIER = "browserMenu"
}
}
diff --git a/app/src/main/res/anim/zoom_out_fade.xml b/app/src/main/res/anim/zoom_out_fade.xml
new file mode 100644
index 000000000..720b5bf3c
--- /dev/null
+++ b/app/src/main/res/anim/zoom_out_fade.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
index 4a9431c33..153eee267 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -58,6 +58,7 @@
+ app:popEnterAnim="@anim/zoom_out_fade" />