diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
index 1ff2133704..1358dda5d9 100644
--- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
+++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt
@@ -19,12 +19,12 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import androidx.navigation.Navigation
+import androidx.transition.TransitionInflater
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.component_search.*
import kotlinx.android.synthetic.main.fragment_browser.*
import kotlinx.android.synthetic.main.fragment_browser.view.*
import kotlinx.android.synthetic.main.fragment_search.*
-import kotlinx.android.synthetic.main.layout_quick_action_sheet.view.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.IO
@@ -116,6 +116,7 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ postponeEnterTransition()
job = Job()
}
@@ -128,6 +129,7 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
customTabSessionId = arguments?.getString(IntentProcessor.ACTIVE_SESSION_ID)
val view = inflater.inflate(R.layout.fragment_browser, container, false)
+ view.browserLayout.transitionName = "$TAB_ITEM_TRANSITION_NAME${getSessionById()?.id}"
toolbarComponent = ToolbarComponent(
view.browserLayout,
@@ -179,13 +181,13 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
QuickActionViewModel::class.java
) {
QuickActionViewModel(
- QuickActionState(
- readable = getSessionById()?.readerable ?: false,
- bookmarked = findBookmarkedURL(getSessionById()),
- readerActive = getSessionById()?.readerMode ?: false,
- bounceNeeded = false
+ QuickActionState(
+ readable = getSessionById()?.readerable ?: false,
+ bookmarked = findBookmarkedURL(getSessionById()),
+ readerActive = getSessionById()?.readerMode ?: false,
+ bounceNeeded = false
+ )
)
- )
}
)
@@ -206,6 +208,15 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ toolbarIntegration.set(
+ feature = (toolbarComponent.uiView as ToolbarUIView).toolbarIntegration,
+ owner = this,
+ view = view
+ )
+
+ sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
+ startPostponedEnterTransition()
+
val sessionManager = requireComponents.core.sessionManager
contextMenuFeature.set(
@@ -268,12 +279,6 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
view = view
)
- toolbarIntegration.set(
- feature = (toolbarComponent.uiView as ToolbarUIView).toolbarIntegration,
- owner = this,
- view = view
- )
-
val accentHighContrastColor = DefaultThemeManager.resolveAttribute(R.attr.accentHighContrast, requireContext())
sitePermissionsFeature.set(
@@ -771,6 +776,7 @@ class BrowserFragment : Fragment(), BackHandler, CoroutineScope {
}
companion object {
+ private const val TAB_ITEM_TRANSITION_NAME = "tab_item"
private const val REQUEST_CODE_DOWNLOAD_PERMISSIONS = 1
private const val REQUEST_CODE_PROMPT_PERMISSIONS = 2
private const val REQUEST_CODE_APP_PERMISSIONS = 3
diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt
index 03f1f3e2be..74f379e083 100644
--- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt
+++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarIntegration.kt
@@ -5,7 +5,10 @@
package org.mozilla.fenix.components.toolbar
import android.content.Context
+import android.view.ViewGroup
+import androidx.navigation.NavOptions
import androidx.navigation.Navigation
+import androidx.navigation.fragment.FragmentNavigator
import mozilla.components.browser.domains.autocomplete.DomainAutocompleteProvider
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.session.runWithSession
@@ -19,13 +22,13 @@ import mozilla.components.support.base.feature.LifecycleAwareFeature
import mozilla.components.support.ktx.android.view.hideKeyboard
import org.mozilla.fenix.DefaultThemeManager
import org.mozilla.fenix.R
-import org.mozilla.fenix.browser.BrowserFragmentDirections
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.utils.Settings
class ToolbarIntegration(
context: Context,
toolbar: BrowserToolbar,
+ browserLayout: ViewGroup,
toolbarMenu: ToolbarMenu,
domainAutocompleteProvider: DomainAutocompleteProvider,
historyStorage: HistoryStorage,
@@ -53,8 +56,18 @@ class ToolbarIntegration(
sessionManager,
{
toolbar.hideKeyboard()
+ // We need to dynamically add the options here because if you do it in XML it overwrites
+ val options = NavOptions.Builder().setPopUpTo(R.id.browserFragment, false)
+ .setEnterAnim(R.anim.fade_in).setExitAnim(R.anim.fade_out).build()
+ val extras =
+ FragmentNavigator.Extras.Builder()
+ .addSharedElement(
+ browserLayout,
+ "$TAB_ITEM_TRANSITION_NAME${sessionManager.selectedSession?.id}"
+ )
+ .build()
Navigation.findNavController(toolbar)
- .navigate(BrowserFragmentDirections.actionBrowserFragmentToHomeFragment())
+ .navigate(R.id.action_browserFragment_to_homeFragment, null, options, extras)
},
isPrivate
)
@@ -74,8 +87,10 @@ class ToolbarIntegration(
toolbar,
context.components.core.sessionManager,
sessionId,
- ToolbarFeature.UrlRenderConfiguration(PublicSuffixList(context),
- DefaultThemeManager.resolveAttribute(R.attr.primaryText, context), renderStyle = renderStyle)
+ ToolbarFeature.UrlRenderConfiguration(
+ PublicSuffixList(context),
+ DefaultThemeManager.resolveAttribute(R.attr.primaryText, context), renderStyle = renderStyle
+ )
)
private var menuPresenter = MenuPresenter(toolbar, context.components.core.sessionManager, sessionId)
@@ -88,4 +103,8 @@ class ToolbarIntegration(
menuPresenter.stop()
toolbarPresenter.stop()
}
+
+ companion object {
+ private const val TAB_ITEM_TRANSITION_NAME = "tab_item"
+ }
}
diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt
index cad790a37d..59ad3d386e 100644
--- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt
+++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarUIView.kt
@@ -108,6 +108,7 @@ class ToolbarUIView(
toolbarIntegration = ToolbarIntegration(
this,
view,
+ container,
menuToolbar,
ShippedDomainsProvider().also { it.initialize(this) },
components.core.historyStorage,
diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
index b3e6c72057..c730c5d400 100644
--- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
+++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt
@@ -19,6 +19,8 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.navigation.Navigation
+import androidx.navigation.fragment.FragmentNavigator
+import androidx.transition.TransitionInflater
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.fragment_home.view.*
import kotlinx.coroutines.CoroutineScope
@@ -46,6 +48,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.collections.CreateCollectionViewModel
import org.mozilla.fenix.collections.SaveCollectionStep
import org.mozilla.fenix.components.metrics.Event
+import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.allowUndo
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.urlToTrimmedHost
@@ -96,6 +99,12 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ postponeEnterTransition()
+ sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
+ }
+
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@@ -156,6 +165,13 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
}
}
+ postponeEnterTransition()
+ sessionControlComponent.view.getViewTreeObserver()
+ .addOnPreDrawListener {
+ startPostponedEnterTransition()
+ true
+ }
+
view.menuButton.setOnClickListener {
homeMenu?.menuBuilder?.build(requireContext())?.show(
anchor = it,
@@ -285,7 +301,12 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
val session =
requireComponents.core.sessionManager.findSessionById(action.sessionId)
requireComponents.core.sessionManager.select(session!!)
- (activity as HomeActivity).openToBrowser(BrowserDirection.FromHome)
+ val directions = HomeFragmentDirections.actionHomeFragmentToBrowserFragment(null)
+ val extras =
+ FragmentNavigator.Extras.Builder()
+ .addSharedElement(action.tabView, "$TAB_ITEM_TRANSITION_NAME${action.sessionId}")
+ .build()
+ Navigation.findNavController(action.tabView).navigate(directions, extras)
}
is TabAction.Close -> {
if (deleteSessionJob == null) removeTabWithUndo(action.sessionId) else {
@@ -401,7 +422,8 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
(activity as HomeActivity).openToBrowserAndLoad(
searchTermOrURL = action.tab.url,
newTab = true,
- from = BrowserDirection.FromHome)
+ from = BrowserDirection.FromHome
+ )
}
is CollectionAction.OpenTabs -> {
invokePendingDeleteJobs()
@@ -662,6 +684,7 @@ class HomeFragment : Fragment(), CoroutineScope, AccountObserver {
override fun onProfileUpdated(profile: Profile) { emitAccountChanges() }
companion object {
+ private const val TAB_ITEM_TRANSITION_NAME = "tab_item"
private const val toolbarPaddingDp = 12f
private const val MOTION_LAYOUT_PROGRESS_ROUND_POINT = 0.25f
}
diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlComponent.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlComponent.kt
index ac097f8f5f..b695b3f96b 100644
--- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlComponent.kt
+++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlComponent.kt
@@ -7,6 +7,7 @@ package org.mozilla.fenix.home.sessioncontrol
import android.content.Context
import android.graphics.Bitmap
import android.os.Parcelable
+import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observer
@@ -97,7 +98,7 @@ sealed class TabAction : Action {
object Add : TabAction()
object ShareTabs : TabAction()
data class CloseAll(val private: Boolean) : TabAction()
- data class Select(val sessionId: String) : TabAction()
+ data class Select(val tabView: View, val sessionId: String) : TabAction()
data class Close(val sessionId: String) : TabAction()
data class Share(val sessionId: String) : TabAction()
object PrivateBrowsingLearnMore : TabAction()
diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TabViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TabViewHolder.kt
index 2cd21bd363..3e3e02bc44 100644
--- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TabViewHolder.kt
+++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/TabViewHolder.kt
@@ -53,7 +53,7 @@ class TabViewHolder(
close_tab_button.increaseTapArea(buttonIncreaseDps)
item_tab.setOnClickListener {
- actionEmitter.onNext(TabAction.Select(tab?.sessionId!!))
+ actionEmitter.onNext(TabAction.Select(it, tab?.sessionId!!))
}
item_tab.setOnLongClickListener {
@@ -85,6 +85,7 @@ class TabViewHolder(
fun bindSession(tab: Tab) {
this.tab = tab
updateTabUI(tab)
+ item_tab.transitionName = "$TAB_ITEM_TRANSITION_NAME${tab.sessionId}"
updateSelected(tab.selected ?: false)
}
@@ -105,6 +106,7 @@ class TabViewHolder(
}
companion object {
+ private const val TAB_ITEM_TRANSITION_NAME = "tab_item"
const val LAYOUT_ID = R.layout.tab_list_row
const val buttonIncreaseDps = 12
const val favIconBorderRadiusInPx = 8
diff --git a/app/src/main/res/layout/component_session_control.xml b/app/src/main/res/layout/component_session_control.xml
index 36941dea92..345c777f32 100644
--- a/app/src/main/res/layout/component_session_control.xml
+++ b/app/src/main/res/layout/component_session_control.xml
@@ -3,11 +3,12 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
\ No newline at end of file
+ android:transitionGroup="false" />
diff --git a/app/src/main/res/layout/fragment_browser.xml b/app/src/main/res/layout/fragment_browser.xml
index e9c06b4b1d..7d9f6e94bd 100644
--- a/app/src/main/res/layout/fragment_browser.xml
+++ b/app/src/main/res/layout/fragment_browser.xml
@@ -24,7 +24,7 @@
android:clipToPadding="true"
app:behavior_hideable="true"
app:behavior_peekHeight="12dp"
- app:layout_behavior="org.mozilla.fenix.quickactionsheet.QuickActionSheetBehavior"/>
+ app:layout_behavior="org.mozilla.fenix.quickactionsheet.QuickActionSheetBehavior" />
+ android:visibility="gone" />
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index efe972332d..6c4a134f27 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -13,6 +13,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?homeBackground"
+ android:clipChildren="false"
app:layoutDescription="@xml/home_scene"
tools:context=".home.HomeFragment">
diff --git a/app/src/main/res/navigation/nav_graph.xml b/app/src/main/res/navigation/nav_graph.xml
index 9087109ece..ca0f7f89d6 100644
--- a/app/src/main/res/navigation/nav_graph.xml
+++ b/app/src/main/res/navigation/nav_graph.xml
@@ -28,7 +28,9 @@
app:destination="@id/searchFragment" />
+ app:destination="@id/browserFragment"
+ app:enterAnim="@anim/fade_in"
+ app:exitAnim="@anim/fade_out" />
@@ -113,9 +115,7 @@
tools:layout="@layout/fragment_browser">
+ app:destination="@id/homeFragment" />
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 9f36cc663d..e70c78f96a 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -6,6 +6,7 @@