@@ -153,6 +153,13 @@ open class CardBrowser :
153153 * When the list is changed, the position member of its elements should get changed. */
154154 private val cards get() = viewModel.cards
155155 private lateinit var deckSpinnerSelection: DeckSpinnerSelection
156+ private var lastSelectedPosition
157+ get() = viewModel.lastSelectedPosition
158+ set(value) {
159+ viewModel.lastSelectedPosition = value
160+ }
161+ private var oldCardTopOffset: Int = 0
162+ private var oldCardId: Long? = null
156163
157164 @VisibleForTesting
158165 lateinit var cardsListView: RecyclerView
@@ -349,11 +356,23 @@ open class CardBrowser :
349356
350357 @VisibleForTesting
351358 fun onLongPress (id : CardOrNoteId ) {
352- // click on whole cell triggers select
359+ // Cell select triggers multi- select mode
353360 if (viewModel.isInMultiSelectMode && viewModel.lastSelectedId != null ) {
361+ // Select rows between the last selected ID and the current ID
354362 viewModel.selectRowsBetween(viewModel.lastSelectedId!! , id)
355363 } else {
356- viewModel.toggleRowSelection(id)
364+ launchCatchingTask {
365+ val position = getPositionForId(id)
366+ // Save scrolling state to preserve UI consistency
367+ lastSelectedPosition = position
368+ saveScrollingState(position)
369+
370+ // Toggle selection of the card
371+ viewModel.toggleRowSelection(id)
372+
373+ // Notify adapter about changes
374+ cardsAdapter.notifyDataSetChanged()
375+ }
357376 }
358377 }
359378
@@ -484,6 +503,7 @@ open class CardBrowser :
484503 // show title and hide spinner
485504 actionBarTitle.visibility = View .VISIBLE
486505 deckSpinnerSelection.setSpinnerVisibility(View .GONE )
506+ autoScrollTo(lastSelectedPosition)
487507 } else {
488508 Timber .d(" end multiselect mode" )
489509 // update adapter to remove check boxes
@@ -1909,6 +1929,35 @@ open class CardBrowser :
19091929 viewModel : CardBrowserViewModel ,
19101930 ): Intent = NoteEditorLauncher .AddNoteFromCardBrowser (viewModel).getIntent(context)
19111931 }
1932+
1933+ private suspend fun saveScrollingState (position : Int ) {
1934+ // Save the current card id and its top offset
1935+ oldCardId = viewModel.queryCardIdAtPosition(position)
1936+ oldCardTopOffset = calculateTopOffset(position)
1937+ }
1938+
1939+ private fun calculateTopOffset (cardPosition : Int ): Int {
1940+ // Calculate the top offset of the card at the given position
1941+ val layoutManager = cardsListView.layoutManager as ? LinearLayoutManager ? : return 0
1942+ val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
1943+ val view = cardsListView.getChildAt(cardPosition - firstVisiblePosition)
1944+ return view?.top ? : 0
1945+ }
1946+
1947+ private fun autoScrollTo (newPosition : Int ) {
1948+ (cardsListView.layoutManager as ? LinearLayoutManager )?.scrollToPositionWithOffset(newPosition, oldCardTopOffset)
1949+ }
1950+
1951+ fun getPositionForId (id : CardOrNoteId ): Int {
1952+ // Search through rowCollection for the CardOrNoteId and return its position
1953+ val rowCollection = cardsAdapter.rowCollection
1954+ for (position in 0 until rowCollection.size) {
1955+ if (rowCollection[position] == id) {
1956+ return position
1957+ }
1958+ }
1959+ return RecyclerView .NO_POSITION
1960+ }
19121961}
19131962
19141963suspend fun searchForRows (
0 commit comments