mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-19 09:25:34 +00:00
[fenix] For https://github.com/mozilla-mobile/fenix/issues/15115 - Part 3: Implement a grid view layout for the tabs
Co-authored-by: Abhijit Valluri avalluri2@bloomberg.net
This commit is contained in:
parent
ded4f5cbbb
commit
d7f46fa9f5
@ -19,6 +19,7 @@ import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.metrics
|
||||
import org.mozilla.fenix.ext.settings
|
||||
|
||||
class FenixTabsAdapter(
|
||||
private val context: Context,
|
||||
@ -27,7 +28,7 @@ class FenixTabsAdapter(
|
||||
viewHolderProvider = { parentView ->
|
||||
TabTrayViewHolder(
|
||||
LayoutInflater.from(context).inflate(
|
||||
R.layout.tab_tray_item,
|
||||
if (context.settings().gridTabView) R.layout.tab_tray_grid_item else R.layout.tab_tray_item,
|
||||
parentView,
|
||||
false
|
||||
),
|
||||
|
@ -162,6 +162,13 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler
|
||||
if (newConfig.orientation != currentOrientation) {
|
||||
tabTrayView.dismissMenu()
|
||||
tabTrayView.expand()
|
||||
|
||||
if (requireContext().settings().gridTabView) {
|
||||
// Update the number of columns to use in the grid view when the screen
|
||||
// orientation changes.
|
||||
tabTrayView.updateTabsTrayLayout()
|
||||
}
|
||||
|
||||
currentOrientation = newConfig.orientation
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ import androidx.core.view.updatePadding
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.ConcatAdapter
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
@ -174,11 +175,9 @@ class TabTrayView(
|
||||
)
|
||||
}
|
||||
|
||||
updateTabsTrayLayout()
|
||||
|
||||
view.tabsTray.apply {
|
||||
layoutManager = LinearLayoutManager(container.context).apply {
|
||||
reverseLayout = true
|
||||
stackFromEnd = true
|
||||
}
|
||||
adapter = concatAdapter
|
||||
|
||||
tabsTouchHelper = TabsTouchHelper(
|
||||
@ -190,11 +189,15 @@ class TabTrayView(
|
||||
|
||||
tabsAdapter.tabTrayInteractor = interactor
|
||||
tabsAdapter.onTabsUpdated = {
|
||||
// Put the 'Add to collections' button after the tabs have loaded.
|
||||
concatAdapter.addAdapter(0, collectionsButtonAdapter)
|
||||
|
||||
// Put the Synced Tabs adapter at the end.
|
||||
concatAdapter.addAdapter(0, syncedTabsController.adapter)
|
||||
if (view.context.settings().gridTabView) {
|
||||
concatAdapter.addAdapter(collectionsButtonAdapter)
|
||||
concatAdapter.addAdapter(syncedTabsController.adapter)
|
||||
} else {
|
||||
// Put the 'Add to collections' button after the tabs have loaded.
|
||||
concatAdapter.addAdapter(0, collectionsButtonAdapter)
|
||||
// Put the Synced Tabs adapter at the end.
|
||||
concatAdapter.addAdapter(syncedTabsController.adapter)
|
||||
}
|
||||
|
||||
if (hasAccessibilityEnabled) {
|
||||
tabsAdapter.notifyItemRangeChanged(0, tabs.size)
|
||||
@ -345,6 +348,53 @@ class TabTrayView(
|
||||
var mode: Mode = Mode.Normal
|
||||
private set
|
||||
|
||||
fun updateTabsTrayLayout() {
|
||||
if (container.context.settings().gridTabView) {
|
||||
setupGridTabView()
|
||||
} else {
|
||||
setupListTabView()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupGridTabView() {
|
||||
view.tabsTray.apply {
|
||||
val gridLayoutManager =
|
||||
GridLayoutManager(container.context, getNumberOfGridColumns(container.context))
|
||||
|
||||
gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
|
||||
override fun getSpanSize(position: Int): Int {
|
||||
val numTabs = tabsAdapter.itemCount
|
||||
return if (position < numTabs) {
|
||||
1
|
||||
} else {
|
||||
getNumberOfGridColumns(container.context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layoutManager = gridLayoutManager
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of columns that will fit in the grid layout for the current screen.
|
||||
*/
|
||||
private fun getNumberOfGridColumns(context: Context): Int {
|
||||
val displayMetrics = context.resources.displayMetrics
|
||||
val screenWidthDp = displayMetrics.widthPixels / displayMetrics.density
|
||||
val columnCount = (screenWidthDp / COLUMN_WIDTH_DP).toInt()
|
||||
return if (columnCount >= 2) columnCount else 2
|
||||
}
|
||||
|
||||
private fun setupListTabView() {
|
||||
view.tabsTray.apply {
|
||||
layoutManager = LinearLayoutManager(container.context).apply {
|
||||
reverseLayout = true
|
||||
stackFromEnd = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateState(state: TabTrayDialogFragmentState) {
|
||||
val oldMode = mode
|
||||
|
||||
@ -620,6 +670,7 @@ class TabTrayView(
|
||||
private const val SLIDE_OFFSET = 0
|
||||
private const val SELECTION_DELAY = 500
|
||||
private const val NORMAL_HANDLE_PERCENT_WIDTH = 0.1F
|
||||
private const val COLUMN_WIDTH_DP = 180
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import org.mozilla.fenix.ext.getMediaStateForSession
|
||||
import org.mozilla.fenix.ext.increaseTapArea
|
||||
import org.mozilla.fenix.ext.removeAndDisable
|
||||
import org.mozilla.fenix.ext.removeTouchDelegate
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.ext.showAndEnable
|
||||
import org.mozilla.fenix.ext.toShortUrl
|
||||
import org.mozilla.fenix.utils.Do
|
||||
@ -161,6 +162,11 @@ class TabTrayViewHolder(
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun updateBackgroundColor(isSelected: Boolean) {
|
||||
if (itemView.context.settings().gridTabView) {
|
||||
// No need to set a background color in the item view for grid tabs.
|
||||
return
|
||||
}
|
||||
|
||||
val color = if (isSelected) {
|
||||
R.color.tab_tray_item_selected_background_normal_theme
|
||||
} else {
|
||||
@ -180,10 +186,17 @@ class TabTrayViewHolder(
|
||||
}
|
||||
|
||||
private fun loadIntoThumbnailView(thumbnailView: ImageView, id: String) {
|
||||
val thumbnailSize = max(
|
||||
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_thumbnail_height),
|
||||
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_thumbnail_width)
|
||||
)
|
||||
val thumbnailSize = if (itemView.context.settings().gridTabView) {
|
||||
max(
|
||||
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_grid_item_thumbnail_height),
|
||||
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_grid_item_thumbnail_width)
|
||||
)
|
||||
} else {
|
||||
max(
|
||||
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_list_item_thumbnail_height),
|
||||
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_list_item_thumbnail_width)
|
||||
)
|
||||
}
|
||||
imageLoader.loadIntoView(thumbnailView, ImageLoadRequest(id, thumbnailSize))
|
||||
}
|
||||
|
||||
|
109
app/src/main/res/layout/tab_tray_grid_item.xml
Normal file
109
app/src/main/res/layout/tab_tray_grid_item.xml
Normal file
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
<com.google.android.material.card.MaterialCardView 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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
app:cardBackgroundColor="@color/photonWhite"
|
||||
app:cardCornerRadius="@dimen/tab_tray_grid_item_border_radius"
|
||||
app:cardElevation="0dp"
|
||||
app:strokeColor="@color/photonLightGrey30"
|
||||
app:strokeWidth="1dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/tab_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/play_pause_button"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginTop="23dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/mozac_feature_media_notification_action_pause"
|
||||
android:elevation="10dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/media_state_play" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/mozac_browser_tabstray_favicon_icon"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintBottom_toTopOf="@id/mozac_browser_tabstray_card"
|
||||
app:layout_constraintStart_toStartOf="@id/mozac_browser_tabstray_card"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/mozac_browser_tabstray_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:ellipsize="none"
|
||||
android:fadingEdgeLength="25dp"
|
||||
android:paddingHorizontal="7dp"
|
||||
android:paddingVertical="5dp"
|
||||
android:requiresFadingEdge="horizontal"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/photonInk80"
|
||||
android:textSize="14sp"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintEnd_toStartOf="@id/mozac_browser_tabstray_close"
|
||||
app:layout_constraintStart_toEndOf="@id/mozac_browser_tabstray_favicon_icon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Example Domain" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/mozac_browser_tabstray_close"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/close_tab"
|
||||
app:layout_constraintBottom_toTopOf="@id/mozac_browser_tabstray_card"
|
||||
app:layout_constraintEnd_toEndOf="@id/mozac_browser_tabstray_card"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/mozac_ic_close"
|
||||
app:tint="@color/photonInk80" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/mozac_browser_tabstray_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/tab_tray_grid_item_thumbnail_height"
|
||||
android:layout_marginTop="30dp"
|
||||
android:backgroundTint="?tabTrayThumbnailItemBackground"
|
||||
app:cardBackgroundColor="@color/photonWhite"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/default_tab_thumbnail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:importantForAccessibility="no"
|
||||
android:padding="22dp"
|
||||
app:srcCompat="@drawable/mozac_ic_globe"
|
||||
app:tint="?tabTrayThumbnailIcon" />
|
||||
|
||||
<mozilla.components.browser.tabstray.thumbnail.TabThumbnailView
|
||||
android:id="@+id/mozac_browser_tabstray_thumbnail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@string/mozac_browser_tabstray_open_tab" />
|
||||
|
||||
<include layout="@layout/checkbox_item" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
@ -28,8 +28,8 @@
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/mozac_browser_tabstray_card"
|
||||
android:layout_width="@dimen/tab_tray_thumbnail_width"
|
||||
android:layout_height="@dimen/tab_tray_thumbnail_height"
|
||||
android:layout_width="@dimen/tab_tray_list_item_thumbnail_width"
|
||||
android:layout_height="@dimen/tab_tray_list_item_thumbnail_height"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:backgroundTint="?tabTrayThumbnailItemBackground"
|
||||
|
@ -171,8 +171,12 @@
|
||||
|
||||
<!-- Tabs Tray -->
|
||||
<dimen name="tab_tray_top_offset">40dp</dimen>
|
||||
<dimen name="tab_tray_thumbnail_width">92dp</dimen>
|
||||
<dimen name="tab_tray_thumbnail_height">69dp</dimen>
|
||||
<dimen name="tab_tray_list_item_thumbnail_width">92dp</dimen>
|
||||
<dimen name="tab_tray_list_item_thumbnail_height">69dp</dimen>
|
||||
<dimen name="tab_tray_grid_item_thumbnail_width">156dp</dimen>
|
||||
<dimen name="tab_tray_grid_item_thumbnail_height">156dp</dimen>
|
||||
<dimen name="tab_tray_grid_item_border_radius">8dp</dimen>
|
||||
<dimen name="tab_tray_grid_item_selected_border_width">2dp</dimen>
|
||||
<dimen name="tab_tray_favicon_border_radius">4dp</dimen>
|
||||
<dimen name="tab_tray_multiselect_handle_height">11dp</dimen>
|
||||
<dimen name="tab_tray_multiselect_handle_top_margin">0dp</dimen>
|
||||
|
Loading…
Reference in New Issue
Block a user