Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import com.ichi2.anki.browser.BrowserColumnSelectionRecyclerItem.UsageItem
import com.ichi2.anki.browser.ColumnUsage.AVAILABLE
import com.ichi2.anki.databinding.ItemBrowserColumnsEntryBinding
import com.ichi2.anki.databinding.ItemBrowserColumnsHeadingBinding
import java.util.Collections
import com.ichi2.anki.utils.ext.swapPositions

class BrowserColumnSelectionAdapter(
val items: MutableList<BrowserColumnSelectionRecyclerItem>,
Expand Down Expand Up @@ -202,7 +202,7 @@ open class BrowserColumnSelectionTouchHelperCallback(
// `Available` should always be the first element, so don't allow moving above it
if (toPosition == 0) return false

Collections.swap(items, fromPosition, toPosition)
items.swapPositions(fromPosition, toPosition)
recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.ichi2.anki.R
import com.ichi2.anki.databinding.ItemReviewerMenuBinding
import com.ichi2.anki.databinding.ItemReviewerMenuDisplayTypeBinding
import java.util.Objects

/**
* Provides bindings from menu items and display types (headings) to [RecyclerView] views
Expand All @@ -37,8 +38,12 @@ import com.ichi2.anki.databinding.ItemReviewerMenuDisplayTypeBinding
* @see ReviewerMenuSettingsRecyclerItem
*/
class ReviewerMenuSettingsAdapter(
private val items: List<ReviewerMenuSettingsRecyclerItem>,
private val items: MutableList<ReviewerMenuSettingsRecyclerItem>,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
init {
setHasStableIds(true)
}

override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int,
Expand Down Expand Up @@ -72,6 +77,11 @@ class ReviewerMenuSettingsAdapter(

override fun getItemViewType(position: Int): Int = items[position].viewType

override fun getItemId(position: Int): Long {
val item = items[position]
return Objects.hash(item.viewType, item).toLong()
}

private var onDragHandleTouchedListener: ((RecyclerView.ViewHolder) -> Unit)? = null

fun setOnDragHandleTouchedListener(listener: (RecyclerView.ViewHolder) -> Unit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class ReviewerMenuSettingsFragment :
listOf(ReviewerMenuSettingsRecyclerItem.DisplayType(displayType)) +
menuItems.getValue(displayType).map { ReviewerMenuSettingsRecyclerItem.Action(it) }

val recyclerViewItems = MenuDisplayType.entries.flatMap { section(it) }
val recyclerViewItems = MenuDisplayType.entries.flatMap { section(it) }.toMutableList()

val callback = ReviewerMenuSettingsTouchHelperCallback(recyclerViewItems)
callback.setOnClearViewListener(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package com.ichi2.anki.preferences.reviewer

import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView
import java.util.Collections
import com.ichi2.anki.utils.ext.swapPositions

/**
* A [ItemTouchHelper.Callback] for the [ReviewerMenuSettingsAdapter].
Expand All @@ -29,7 +29,7 @@ import java.util.Collections
* (see [clearView]).
*/
class ReviewerMenuSettingsTouchHelperCallback(
private val items: List<ReviewerMenuSettingsRecyclerItem>,
private val items: MutableList<ReviewerMenuSettingsRecyclerItem>,
) : ItemTouchHelper.Callback() {
private val movementFlags = makeMovementFlags(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0)

Expand All @@ -54,7 +54,7 @@ class ReviewerMenuSettingsTouchHelperCallback(
// `Always show` should always be the first element, so don't allow moving above it
if (toPosition == 0) return false

Collections.swap(items, fromPosition, toPosition)
items.swapPositions(fromPosition, toPosition)
recyclerView.adapter?.notifyItemMoved(fromPosition, toPosition)
return true
}
Expand Down
24 changes: 24 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/anki/utils/ext/MutableList.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: 2026 Brayan Oliveira <brayandso.dev@gmail.com>
// SPDX-License-Identifier: GPL-3.0-or-later
package com.ichi2.anki.utils.ext

import java.util.Collections

/**
* Moves an item within a MutableList by swapping adjacent elements. This is particularly
* optimized for [androidx.recyclerview.widget.ItemTouchHelper] drag-and-drop operations.
*/
fun <T> MutableList<T>.swapPositions(
fromPosition: Int,
toPosition: Int,
) {
if (fromPosition < toPosition) {
for (i in fromPosition until toPosition) {
Collections.swap(this, i, i + 1)
}
} else {
for (i in fromPosition downTo toPosition + 1) {
Collections.swap(this, i, i - 1)
}
}
}
Loading