From a59f2baa3a0188406d93e581223a7258a5396172 Mon Sep 17 00:00:00 2001 From: lynxnb Date: Sun, 31 Jul 2022 01:56:22 +0200 Subject: [PATCH] Add a `SelectableGenericAdapter` as subclass of `GenericAdapter` `SelectableGenericAdapter` extends `GenericAdapter` with support for marking one item as selected. --- .../emu/skyline/adapter/GenericAdapter.kt | 48 ++++++++++++++++++- .../emu/skyline/adapter/GenericListItem.kt | 4 ++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/emu/skyline/adapter/GenericAdapter.kt b/app/src/main/java/emu/skyline/adapter/GenericAdapter.kt index 251c90c8..d4bd74ae 100644 --- a/app/src/main/java/emu/skyline/adapter/GenericAdapter.kt +++ b/app/src/main/java/emu/skyline/adapter/GenericAdapter.kt @@ -21,7 +21,7 @@ typealias OnFilterPublishedListener = () -> Unit /** * Can handle any view types with [GenericListItem] implemented, [GenericListItem] are differentiated by the return value of [GenericListItem.getViewBindingFactory] */ -class GenericAdapter : RecyclerView.Adapter>(), Filterable { +open class GenericAdapter : RecyclerView.Adapter>(), Filterable { companion object { private val DIFFER = object : DiffUtil.ItemCallback>() { override fun areItemsTheSame(oldItem : GenericListItem, newItem : GenericListItem) = oldItem.areItemsTheSame(newItem) @@ -139,3 +139,49 @@ class GenericAdapter : RecyclerView.Adapter>(), F } } } + +/** + * A [GenericAdapter] that supports marking one item as selected. List items that need to access the selected position should inherit from [SelectableGenericListItem] + */ +class SelectableGenericAdapter(private val defaultPosition : Int) : GenericAdapter() { + var selectedPosition : Int = defaultPosition + + /** + * Sets the selected position to [position] and notifies previous and new selected positions + */ + fun selectAndNotify(position : Int) { + val previousSelectedPosition = selectedPosition + selectedPosition = position + notifyItemChanged(previousSelectedPosition) + notifyItemChanged(position) + } + + /** + * Sets the selected position to [position] and only notifies the previous selected position + */ + fun selectAndNotifyPrevious(position : Int) { + val previousSelectedPosition = selectedPosition + selectedPosition = position + notifyItemChanged(previousSelectedPosition) + } + + /** + * Removes the item at [position] from the list and updates the selected position accordingly + */ + override fun removeItemAt(position: Int) { + super.removeItemAt(position) + if (position < selectedPosition) + selectedPosition-- + else if (position == selectedPosition) + selectAndNotify(defaultPosition) + } + + /** + * Inserts the given item to the list at [position] and updates the selected position accordingly + */ + override fun addItemAt(position : Int, item : GenericListItem) { + super.addItemAt(position, item) + if (position <= selectedPosition) + selectedPosition++ + } +} diff --git a/app/src/main/java/emu/skyline/adapter/GenericListItem.kt b/app/src/main/java/emu/skyline/adapter/GenericListItem.kt index f1194449..2d2522de 100644 --- a/app/src/main/java/emu/skyline/adapter/GenericListItem.kt +++ b/app/src/main/java/emu/skyline/adapter/GenericListItem.kt @@ -37,3 +37,7 @@ abstract class GenericListItem { open val fullSpan : Boolean = false } + +abstract class SelectableGenericListItem : GenericListItem() { + val selectableAdapter get() = super.adapter as SelectableGenericAdapter? +}