Skip to content

Commit 67dc5e5

Browse files
committed
Fix missing auto-scroll feature in RecyclerView when switching to multiselectview
1 parent 6495275 commit 67dc5e5

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

19141963
suspend fun searchForRows(

AnkiDroid/src/main/java/com/ichi2/anki/browser/BrowserMultiColumnAdapter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class BrowserMultiColumnAdapter(
6363
val fontSizeScalePercent =
6464
sharedPrefs().getInt("relativeCardBrowserFontSize", DEFAULT_FONT_SIZE_RATIO)
6565

66-
private val rowCollection: BrowserRowCollection
66+
val rowCollection: BrowserRowCollection
6767
get() = viewModel.cards
6868

6969
private var originalTextSize = -1.0f

AnkiDroid/src/main/java/com/ichi2/anki/browser/CardBrowserViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class CardBrowserViewModel(
181181
internal suspend fun queryAllCardIds() = cards.queryCardIds()
182182

183183
var lastSelectedId: CardOrNoteId? = null
184-
184+
var lastSelectedPosition = 0
185185
val flowOfIsInMultiSelectMode =
186186
flowOfSelectedRows
187187
.map { it.isNotEmpty() }

0 commit comments

Comments
 (0)