Commit 72007590 authored by Marc Leclair's avatar Marc Leclair Committed by Jeff Boek
Browse files

#7700 squash commit and fixing toolbar to switxh to top with coordinatorlayout

parent c0d7bc5b
......@@ -19,14 +19,10 @@ import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
import androidx.constraintlayout.widget.ConstraintSet.END
import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
import androidx.constraintlayout.widget.ConstraintSet.START
import androidx.constraintlayout.widget.ConstraintSet.TOP
import androidx.core.view.updateLayoutParams
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle
......@@ -41,6 +37,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
import androidx.transition.TransitionInflater
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.fragment_home.view.*
......@@ -91,6 +88,7 @@ import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.utils.FragmentPreDrawManager
import org.mozilla.fenix.utils.allowUndo
import org.mozilla.fenix.whatsnew.WhatsNew
import kotlin.math.abs
import kotlin.math.min
@ExperimentalCoroutinesApi
......@@ -106,7 +104,7 @@ class HomeFragment : Fragment() {
}
private val browsingModeManager get() = (activity as HomeActivity).browsingModeManager
private var homeAppBarOffset = 0
private val singleSessionObserver = object : Session.Observer {
override fun onTitleChanged(session: Session, title: String) {
if (deleteAllSessionsJob == null) emitSessionChanges()
......@@ -142,7 +140,7 @@ class HomeFragment : Fragment() {
private val onboarding by lazy { FenixOnboarding(requireContext()) }
private lateinit var homeFragmentStore: HomeFragmentStore
private lateinit var sessionControlInteractor: SessionControlInteractor
private lateinit var sessionControlView: SessionControlView
private var sessionControlView: SessionControlView? = null
private lateinit var currentMode: CurrentMode
override fun onCreate(savedInstanceState: Bundle?) {
......@@ -195,7 +193,6 @@ class HomeFragment : Fragment() {
activity = activity,
store = homeFragmentStore,
navController = findNavController(),
homeLayout = view.homeLayout,
browsingModeManager = browsingModeManager,
lifecycleScope = viewLifecycleOwner.lifecycleScope,
closeTab = ::closeTab,
......@@ -209,37 +206,32 @@ class HomeFragment : Fragment() {
)
)
sessionControlView = SessionControlView(homeFragmentStore, view.homeLayout, sessionControlInteractor)
view.homeAppBar.addOnOffsetChangedListener(
AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
appBarLayout.alpha =
1.0f - abs(verticalOffset / appBarLayout.totalScrollRange.toFloat())
}
)
updateLayout(view)
setOffset(view)
activity.themeManager.applyStatusBarTheme(activity)
sessionControlView = SessionControlView(homeFragmentStore,
view.sessionControlRecyclerView, sessionControlInteractor)
updateLayout(view)
activity.themeManager.applyStatusBarTheme(activity)
return view
}
private fun updateLayout(view: View) {
val shouldUseBottomToolbar = view.context.settings().shouldUseBottomToolbar
ConstraintSet().apply {
clone(view.homeLayout)
if (shouldUseBottomToolbar) {
connect(sessionControlView.view.id, TOP, view.wordmark.id, BOTTOM)
connect(sessionControlView.view.id, BOTTOM, view.toolbarLayout.id, TOP)
connect(view.toolbarLayout.id, BOTTOM, PARENT_ID, BOTTOM)
connect(view.privateBrowsingButton.id, TOP, PARENT_ID, TOP)
} else {
connect(sessionControlView.view.id, TOP, view.wordmark.id, TOP)
connect(sessionControlView.view.id, BOTTOM, PARENT_ID, BOTTOM)
connect(view.privateBrowsingButton.id, TOP, view.toolbarLayout.id, BOTTOM)
}
connect(sessionControlView.view.id, START, PARENT_ID, START)
connect(sessionControlView.view.id, END, PARENT_ID, END)
applyTo(view.homeLayout)
if(!shouldUseBottomToolbar){
view.toolbarLayout.layoutParams = CoordinatorLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, ConstraintLayout.LayoutParams.WRAP_CONTENT)
.apply {
gravity = Gravity.TOP
}
}
val headingsTopMargins = if (shouldUseBottomToolbar) { HEADER_MARGIN } else { TOP_TOOLBAR_HEADER_MARGIN }
......@@ -253,7 +245,7 @@ class HomeFragment : Fragment() {
topMargin = headingsTopMargins.dpToPx(resources.displayMetrics)
}
sessionControlView.view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
sessionControlView!!.view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = sessionControlViewTopMargin.dpToPx(resources.displayMetrics)
}
......@@ -263,7 +255,6 @@ class HomeFragment : Fragment() {
}
}
}
@ExperimentalCoroutinesApi
@SuppressWarnings("LongMethod")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
......@@ -274,9 +265,8 @@ class HomeFragment : Fragment() {
ViewModelProvider.NewInstanceFactory() // this is a workaround for #4652
}
homeViewModel.layoutManagerState?.also { parcelable ->
sessionControlView.view.layoutManager?.onRestoreInstanceState(parcelable)
sessionControlView!!.view.layoutManager?.onRestoreInstanceState(parcelable)
}
homeLayout?.progress = homeViewModel.motionLayoutProgress
homeViewModel.layoutManagerState = null
}
......@@ -350,6 +340,11 @@ class HomeFragment : Fragment() {
}
}
override fun onDestroyView() {
sessionControlView = null
super.onDestroyView()
}
override fun onStart() {
super.onStart()
subscribeToTabCollections()
......@@ -476,8 +471,7 @@ class HomeFragment : Fragment() {
ViewModelProvider.NewInstanceFactory() // this is a workaround for #4652
}
homeViewModel.layoutManagerState =
sessionControlView.view.layoutManager?.onSaveInstanceState()
homeViewModel.motionLayoutProgress = homeLayout?.progress ?: 0F
sessionControlView!!.view.layoutManager?.onSaveInstanceState()
}
override fun onResume() {
......@@ -485,6 +479,11 @@ class HomeFragment : Fragment() {
hideToolbar()
}
override fun onPause() {
super.onPause()
calculateNewOffset()
}
private fun recommendPrivateBrowsingShortcut() {
context?.let {
val layout = LayoutInflater.from(it)
......@@ -710,7 +709,7 @@ class HomeFragment : Fragment() {
private fun scrollToTheTop() {
lifecycleScope.launch(Main) {
delay(ANIM_SCROLL_DELAY)
sessionControlView.view.smoothScrollToPosition(0)
sessionControlView!!.view.smoothScrollToPosition(0)
}
}
......@@ -720,7 +719,7 @@ class HomeFragment : Fragment() {
) {
if (view != null) {
viewLifecycleOwner.lifecycleScope.launch {
val recyclerView = sessionControlView.view
val recyclerView = sessionControlView!!.view
delay(ANIM_SCROLL_DELAY)
val tabsSize = getListOfSessions().size
......@@ -763,7 +762,7 @@ class HomeFragment : Fragment() {
private fun animateCollection(addedTabsSize: Int, indexOfCollection: Int) {
viewLifecycleOwner.lifecycleScope.launch {
val viewHolder =
sessionControlView.view.findViewHolderForAdapterPosition(indexOfCollection)
sessionControlView!!.view.findViewHolderForAdapterPosition(indexOfCollection)
val border =
(viewHolder as? CollectionViewHolder)?.view?.findViewById<View>(R.id.selected_border)
val listener = object : Animator.AnimatorListener {
......@@ -830,6 +829,23 @@ class HomeFragment : Fragment() {
}
}
private fun calculateNewOffset() {
homeAppBarOffset = ((view!!.findViewById<AppBarLayout>(R.id.homeAppBar)
.layoutParams as CoordinatorLayout.LayoutParams)
.behavior as AppBarLayout.Behavior).topAndBottomOffset
}
private fun setOffset(currentView: View) {
if (homeAppBarOffset <= 0) {
(currentView.homeAppBar.layoutParams as CoordinatorLayout.LayoutParams)
.behavior = AppBarLayout.Behavior().apply {
topAndBottomOffset = this@HomeFragment.homeAppBarOffset
}
} else {
currentView.homeAppBar.setExpanded(false)
}
}
companion object {
private const val NON_TAB_ITEM_NUM = 3
private const val ANIM_SCROLL_DELAY = 100L
......
......@@ -5,7 +5,6 @@
package org.mozilla.fenix.home.sessioncontrol
import android.view.View
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.navigation.NavController
import androidx.navigation.fragment.FragmentNavigator
import kotlinx.coroutines.CoroutineScope
......@@ -151,7 +150,6 @@ class DefaultSessionControlController(
private val activity: HomeActivity,
private val store: HomeFragmentStore,
private val navController: NavController,
private val homeLayout: MotionLayout,
private val browsingModeManager: BrowsingModeManager,
private val lifecycleScope: CoroutineScope,
private val closeTab: (sessionId: String) -> Unit,
......@@ -357,7 +355,6 @@ class DefaultSessionControlController(
}
override fun handleStartBrowsingClicked() {
homeLayout.progress = 0F
hideOnboarding()
}
......
......@@ -5,9 +5,7 @@
package org.mozilla.fenix.home.sessioncontrol
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
......@@ -135,22 +133,18 @@ private fun collectionTabItems(collection: TabCollection) = collection.tabs.mapI
@ExperimentalCoroutinesApi
class SessionControlView(
private val homeFragmentStore: HomeFragmentStore,
private val container: ViewGroup,
override val containerView: View?,
interactor: SessionControlInteractor
) : LayoutContainer {
override val containerView: View?
get() = container
val view: RecyclerView = LayoutInflater.from(container.context)
.inflate(R.layout.component_session_control, container, true)
.findViewById(R.id.home_component)
val view: RecyclerView = containerView as RecyclerView
private val sessionControlAdapter = SessionControlAdapter(interactor)
init {
view.apply {
adapter = sessionControlAdapter
layoutManager = LinearLayoutManager(container.context)
layoutManager = LinearLayoutManager(containerView!!.context)
val itemTouchHelper =
ItemTouchHelper(
SwipeToDeleteCallback(
......
......@@ -2,62 +2,101 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- 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.constraintlayout.motion.widget.MotionLayout
<!-- using an AppBarLayout to replace MotionLayout was done in order to improve Fenix
start up performance. The use of a MotionLayout was worsening our layout measures, especially
with the recycler view -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/homeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?homeBackground"
app:layoutDescription="@xml/home_scene"
tools:context=".home.HomeFragment">
<ImageButton
android:id="@+id/privateBrowsingButton"
android:layout_width="@dimen/glyph_button_height"
android:layout_height="@dimen/glyph_button_height"
android:layout_marginEnd="12dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/content_description_private_browsing_button"
app:srcCompat="@drawable/private_browsing_button"
app:layout_constraintBottom_toTopOf="@+id/wordmark"
app:layout_constraintEnd_toEndOf="parent" />
<ImageView
android:id="@+id/wordmark"
android:layout_width="wrap_content"
android:layout_height="80dp"
android:layout_marginStart="16dp"
android:layout_marginBottom="32dp"
android:adjustViewBounds="true"
android:clickable="false"
android:contentDescription="@string/app_name"
android:focusable="false"
android:importantForAccessibility="no"
app:srcCompat="?fenixLogo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:background="?homeBackground">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/homeAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
app:elevation="0dp"
android:fitsSystemWindows="false">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll">
<ImageButton
android:id="@+id/privateBrowsingButton"
android:layout_width="@dimen/glyph_button_height"
android:layout_height="@dimen/glyph_button_height"
android:layout_marginEnd="12dp"
android:layout_gravity="end"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/content_description_private_browsing_button"
app:srcCompat="@drawable/private_browsing_button"
app:layout_collapseMode="parallax"/>
<ImageView
android:id="@+id/wordmark"
android:layout_width="wrap_content"
android:layout_height="80dp"
android:layout_marginStart="16dp"
android:layout_marginTop="60dp"
android:layout_marginBottom="32dp"
android:adjustViewBounds="true"
android:clickable="false"
android:contentDescription="@string/app_name"
android:focusable="false"
android:importantForAccessibility="no"
app:srcCompat="?fenixLogo"
app:layout_collapseMode="pin"/>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/sessionControlRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:layout_marginBottom="48dp"
android:padding="16dp"
android:scrollbars="none"
android:transitionGroup="false"
android:importantForAccessibility="no"
android:overScrollMode="never"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/toolbarLayout"
android:layout_width="0dp"
android:elevation="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?bottomBarBackground"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
android:layout_gravity="bottom"
tools:context=".home.HomeFragment">
<View
android:id="@+id/bottomBarShadow"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="@color/bottom_bar_shadow"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_bar" />
<View
android:id="@+id/bottom_bar"
android:layout_width="0dp"
android:layout_height="56dp"
android:background="?bottomBarBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"/>
app:layout_constraintStart_toStartOf="parent" />
<org.mozilla.fenix.home.SearchView
android:id="@+id/toolbar_wrapper"
......@@ -70,10 +109,10 @@
android:contentDescription="@string/search_hint"
android:focusable="true"
android:transitionName="toolbar_wrapper_transition"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toBottomOf="@id/bottom_bar"
app:layout_constraintEnd_toStartOf="@+id/add_tab_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
app:layout_constraintTop_toTopOf="@id/bottom_bar">
<ImageView
android:id="@+id/search_engine_icon"
......@@ -108,8 +147,8 @@
android:background="?android:attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/add_tab"
app:srcCompat="@drawable/ic_new"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="@id/bottom_bar"
app:layout_constraintBottom_toBottomOf="@id/bottom_bar"
app:layout_constraintEnd_toStartOf="@+id/menuButton"
app:layout_constraintStart_toEndOf="@id/toolbar_wrapper"/>
......@@ -118,8 +157,9 @@
android:layout_width="36dp"
android:layout_height="48dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintTop_toTopOf="@id/bottom_bar"
app:layout_constraintBottom_toBottomOf="@id/bottom_bar"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.motion.widget.MotionLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
\ No newline at end of file
......@@ -72,7 +72,6 @@ class DefaultSessionControlControllerTest {
activity = activity,
store = store,
navController = navController,
homeLayout = homeLayout,
browsingModeManager = browsingModeManager,
lifecycleScope = MainScope(),
closeTab = closeTab,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment