From 917783a14101b8648a806ad2d3551d4572a93069 Mon Sep 17 00:00:00 2001 From: Jonathan Almeida Date: Thu, 25 Mar 2021 17:22:41 -0400 Subject: [PATCH] Issue #18443: Fix changes between grid/list viewholders --- .../fenix/tabstray/TabsTrayGridViewHolder.kt | 6 +++-- .../fenix/tabstray/TabsTrayListViewHolder.kt | 6 +++-- .../fenix/tabstray/TabsTrayViewHolder.kt | 23 +++++++++++++++++- .../mozilla/fenix/tabstray/TrayViewHolders.kt | 2 +- .../tabstray/browser/BrowserTabsAdapter.kt | 12 +++++----- .../tabstray/browser/TabsDetailsLookup.kt | 6 ++--- .../tabstray/browser/TabsItemKeyProvider.kt | 24 +++++++++++++++++++ 7 files changed, 64 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsItemKeyProvider.kt diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayGridViewHolder.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayGridViewHolder.kt index 06abaadd3..15cdfbc79 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayGridViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayGridViewHolder.kt @@ -18,6 +18,7 @@ import org.mozilla.fenix.R import org.mozilla.fenix.ext.increaseTapArea import kotlin.math.max import kotlinx.android.synthetic.main.tab_tray_grid_item.view.tab_tray_grid_item +import org.mozilla.fenix.tabstray.browser.BrowserTrayInteractor /** * A RecyclerView ViewHolder implementation for "tab" items with grid layout. @@ -25,14 +26,15 @@ import kotlinx.android.synthetic.main.tab_tray_grid_item.view.tab_tray_grid_item class TabsTrayGridViewHolder( parent: ViewGroup, imageLoader: ImageLoader, - private val itemView: View = + browserTrayInteractor: BrowserTrayInteractor? = null, + itemView: View = LayoutInflater.from(parent.context).inflate(R.layout.tab_tray_grid_item, parent, false), thumbnailSize: Int = max( itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_grid_item_thumbnail_height), itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_grid_item_thumbnail_width) ) -) : TabsTrayViewHolder(itemView, imageLoader, thumbnailSize) { +) : TabsTrayViewHolder(itemView, imageLoader, thumbnailSize, browserTrayInteractor) { private val closeButton: AppCompatImageButton = itemView.findViewById(R.id.mozac_browser_tabstray_close) diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayListViewHolder.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayListViewHolder.kt index 26d2e1b75..c57362de2 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayListViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayListViewHolder.kt @@ -10,6 +10,7 @@ import android.view.ViewGroup import androidx.core.content.ContextCompat import mozilla.components.concept.base.images.ImageLoader import org.mozilla.fenix.R +import org.mozilla.fenix.tabstray.browser.BrowserTrayInteractor import kotlin.math.max /** @@ -18,14 +19,15 @@ import kotlin.math.max class TabsTrayListViewHolder( parent: ViewGroup, imageLoader: ImageLoader, - private val itemView: View = + browserTrayInteractor: BrowserTrayInteractor? = null, + itemView: View = LayoutInflater.from(parent.context).inflate(R.layout.tab_tray_item, parent, false), thumbnailSize: Int = max( itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_list_item_thumbnail_height), itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_list_item_thumbnail_width) ) -) : TabsTrayViewHolder(itemView, imageLoader, thumbnailSize) { +) : TabsTrayViewHolder(itemView, imageLoader, thumbnailSize, browserTrayInteractor) { override fun updateSelectedTabIndicator(showAsSelected: Boolean) { val color = if (showAsSelected) { diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayViewHolder.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayViewHolder.kt index 5afbba864..f8186a38e 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayViewHolder.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.tabstray +import android.view.MotionEvent import android.view.View import android.widget.ImageButton import android.widget.ImageView @@ -11,6 +12,9 @@ import android.widget.TextView import androidx.annotation.VisibleForTesting import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.widget.AppCompatImageButton +import androidx.core.view.isVisible +import androidx.recyclerview.selection.ItemDetailsLookup +import kotlinx.android.synthetic.main.checkbox_item.view.* import mozilla.components.browser.state.selector.findTabOrCustomTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.tabstray.TabViewHolder @@ -32,14 +36,16 @@ import org.mozilla.fenix.ext.removeAndDisable import org.mozilla.fenix.ext.removeTouchDelegate import org.mozilla.fenix.ext.showAndEnable import org.mozilla.fenix.ext.toShortUrl +import org.mozilla.fenix.tabstray.browser.BrowserTrayInteractor /** * A RecyclerView ViewHolder implementation for "tab" items. */ abstract class TabsTrayViewHolder( - private val itemView: View, + itemView: View, private val imageLoader: ImageLoader, private val thumbnailSize: Int, + private val browserTrayInteractor: BrowserTrayInteractor?, private val store: BrowserStore = itemView.context.components.core.store, private val metrics: MetricController = itemView.context.components.analytics.metrics ) : TabViewHolder(itemView) { @@ -136,6 +142,21 @@ abstract class TabsTrayViewHolder( } } + fun getItemDetails() = object : ItemDetailsLookup.ItemDetails() { + override fun getPosition(): Int = bindingAdapterPosition + override fun getSelectionKey(): Long = itemId + override fun inSelectionHotspot(e: MotionEvent): Boolean { + return browserTrayInteractor?.isMultiSelectMode() == true + } + } + + fun showTabIsMultiSelectEnabled(isSelected: Boolean) { + itemView.selected_mask.isVisible = isSelected + // TODO Enable this with https://github.com/mozilla-mobile/fenix/issues/18656 + // itemView.mozac_browser_tabstray_close.isVisible = + // browserTrayInteractor?.isMultiSelectMode() == false + } + private fun updateFavicon(tab: Tab) { if (tab.icon != null) { faviconView?.visibility = View.VISIBLE diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TrayViewHolders.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TrayViewHolders.kt index 8bb03f408..d8a281300 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TrayViewHolders.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TrayViewHolders.kt @@ -67,7 +67,7 @@ class NormalBrowserTabViewHolder( selectionTracker = SelectionTracker.Builder( "mySelection", trayList, - StableIdKeyProvider(trayList), + TabsItemKeyProvider(trayList), TabsDetailsLookup(trayList), StorageStrategy.createLongStorage() ).withSelectionPredicate( diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/BrowserTabsAdapter.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/BrowserTabsAdapter.kt index 455ea319c..3a9757d51 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/BrowserTabsAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/BrowserTabsAdapter.kt @@ -10,7 +10,6 @@ import androidx.recyclerview.selection.SelectionTracker import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.GridLayoutManager import kotlinx.android.synthetic.main.tab_tray_item.view.* -import mozilla.components.browser.tabstray.TabViewHolder import mozilla.components.browser.thumbnails.loader.ThumbnailLoader import mozilla.components.concept.tabstray.TabsTray import mozilla.components.support.base.observer.Observable @@ -19,6 +18,7 @@ import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.tabstray.TabsTrayGridViewHolder import org.mozilla.fenix.tabstray.TabsTrayListViewHolder +import org.mozilla.fenix.tabstray.TabsTrayViewHolder /** * A [RecyclerView.Adapter] for browser tabs. @@ -28,7 +28,7 @@ class BrowserTabsAdapter( private val interactor: BrowserTrayInteractor, private val layoutManager: (() -> GridLayoutManager)? = null, delegate: Observable = ObserverRegistry() -) : TabsAdapter(delegate) { +) : TabsAdapter(delegate) { /** * The layout types for the tabs. @@ -57,16 +57,16 @@ class BrowserTabsAdapter( } } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TabViewHolder { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TabsTrayViewHolder { return when (viewType) { - ViewType.GRID.ordinal -> TabsTrayGridViewHolder(parent, imageLoader) - else -> TabsTrayListViewHolder(parent, imageLoader) + ViewType.GRID.ordinal -> TabsTrayGridViewHolder(parent, imageLoader, interactor) + else -> TabsTrayListViewHolder(parent, imageLoader, interactor) } } override fun getItemId(position: Int) = position.toLong() - override fun onBindViewHolder(holder: TabViewHolder, position: Int) { + override fun onBindViewHolder(holder: TabsTrayViewHolder, position: Int) { super.onBindViewHolder(holder, position) holder.tab?.let { tab -> diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsDetailsLookup.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsDetailsLookup.kt index 219f314a3..514546a8d 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsDetailsLookup.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsDetailsLookup.kt @@ -8,10 +8,10 @@ import android.view.MotionEvent import androidx.recyclerview.selection.ItemDetailsLookup import androidx.recyclerview.selection.ItemDetailsLookup.ItemDetails import androidx.recyclerview.widget.RecyclerView -import org.mozilla.fenix.tabtray.TabTrayViewHolder +import org.mozilla.fenix.tabstray.TabsTrayViewHolder /** - * An [ItemDetailsLookup] for retrieving the [ItemDetails] of a [TabTrayViewHolder]. + * An [ItemDetailsLookup] for retrieving the [ItemDetails] of a [TabsTrayViewHolder]. */ class TabsDetailsLookup( private val recyclerView: RecyclerView @@ -20,7 +20,7 @@ class TabsDetailsLookup( override fun getItemDetails(event: MotionEvent): ItemDetails? { val view = recyclerView.findChildViewUnder(event.x, event.y) if (view != null) { - val viewHolder = recyclerView.getChildViewHolder(view) as TabTrayViewHolder + val viewHolder = recyclerView.getChildViewHolder(view) as TabsTrayViewHolder return viewHolder.getItemDetails() } return null diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsItemKeyProvider.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsItemKeyProvider.kt new file mode 100644 index 000000000..d138d4232 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabsItemKeyProvider.kt @@ -0,0 +1,24 @@ +/* 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/. */ + +package org.mozilla.fenix.tabstray.browser + +import androidx.recyclerview.selection.ItemKeyProvider +import androidx.recyclerview.widget.RecyclerView + +/** + * A key provider for the browser tabs. + */ +class TabsItemKeyProvider(private val recyclerView: RecyclerView) : + ItemKeyProvider(SCOPE_MAPPED) { + + override fun getKey(position: Int): Long? { + return recyclerView.adapter?.getItemId(position) + } + + override fun getPosition(key: Long): Int { + val viewHolder = recyclerView.findViewHolderForItemId(key) + return viewHolder?.layoutPosition ?: RecyclerView.NO_POSITION + } +}