1
0
Fork 0

For #1287 - Create animation for opening and closing tab from home

master
Emily Kager 2019-05-22 11:46:31 -07:00 committed by Emily Kager
parent 6a8d0f324e
commit 40f2fe5166
14 changed files with 91 additions and 34 deletions

View File

@ -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

View File

@ -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"
}
}

View File

@ -108,6 +108,7 @@ class ToolbarUIView(
toolbarIntegration = ToolbarIntegration(
this,
view,
container,
menuToolbar,
ShippedDomainsProvider().also { it.initialize(this) },
components.core.historyStorage,

View File

@ -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
}

View File

@ -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()

View File

@ -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

View File

@ -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/. -->
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/home_component"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipChildren="false"
android:clipToPadding="false"
android:padding="16dp"
android:scrollbars="none"
android:clipToPadding="false" />
android:transitionGroup="false" />

View File

@ -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" />
<mozilla.components.feature.findinpage.view.FindInPageBar
android:id="@+id/findInPageView"
@ -41,11 +41,11 @@
<mozilla.components.feature.readerview.view.ReaderViewControlsBar
android:id="@+id/readerViewControlsBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?foundation"
android:elevation="24dp"
android:visibility="gone"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:visibility="gone" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -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">
<ImageButton

View File

@ -12,6 +12,7 @@
android:clipToPadding="false"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:transitionGroup="true"
app:cardBackgroundColor="?above"
app:cardCornerRadius="@dimen/tab_corner_radius"
app:cardElevation="5dp">

View File

@ -28,7 +28,9 @@
app:destination="@id/searchFragment" />
<action
android:id="@+id/action_homeFragment_to_browserFragment"
app:destination="@id/browserFragment" />
app:destination="@id/browserFragment"
app:enterAnim="@anim/fade_in"
app:exitAnim="@anim/fade_out" />
<action
android:id="@+id/action_homeFragment_to_libraryFragment"
app:destination="@id/libraryFragment" />
@ -113,9 +115,7 @@
tools:layout="@layout/fragment_browser">
<action
android:id="@+id/action_browserFragment_to_homeFragment"
app:destination="@id/homeFragment"
app:popUpTo="@+id/nav_graph"
app:popUpToInclusive="true" />
app:destination="@id/homeFragment" />
<action
android:id="@+id/action_browserFragment_to_searchFragment"
app:destination="@id/searchFragment" />

View File

@ -6,6 +6,7 @@
<style name="NormalThemeBase" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Android system styling -->
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
<item name="android:progressBarStyleHorizontal">@style/progressBarStyleHorizontal</item>
<item name="android:statusBarColor">@color/foundation_normal_theme</item>
@ -58,6 +59,7 @@
<style name="PrivateThemeBase" parent="Theme.AppCompat.NoActionBar">
<!-- Android system styling -->
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAnimationStyle">@style/WindowAnimationTransition</item>
<item name="android:progressBarStyleHorizontal">@style/progressBarStyleHorizontal</item>
<item name="android:statusBarColor">@color/foundation_private_theme</item>

BIN
face.mp4 100644

Binary file not shown.

BIN
text.mp4 100644

Binary file not shown.