Skip to content

Commit 0b81d11

Browse files
committed
fix #265, allow reordering checklist items by dragging them
1 parent 11155ee commit 0b81d11

File tree

4 files changed

+104
-4
lines changed

4 files changed

+104
-4
lines changed

app/src/main/kotlin/com/simplemobiletools/notes/pro/adapters/ChecklistAdapter.kt

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ import android.graphics.Paint
44
import android.graphics.drawable.Drawable
55
import android.util.TypedValue
66
import android.view.Menu
7+
import android.view.MotionEvent
78
import android.view.View
89
import android.view.ViewGroup
10+
import androidx.recyclerview.widget.ItemTouchHelper
11+
import androidx.recyclerview.widget.RecyclerView
912
import com.simplemobiletools.commons.activities.BaseSimpleActivity
1013
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
1114
import com.simplemobiletools.commons.extensions.applyColorFilter
@@ -17,20 +20,34 @@ import com.simplemobiletools.notes.pro.dialogs.RenameChecklistItemDialog
1720
import com.simplemobiletools.notes.pro.extensions.getTextSize
1821
import com.simplemobiletools.notes.pro.helpers.DONE_CHECKLIST_ITEM_ALPHA
1922
import com.simplemobiletools.notes.pro.interfaces.ChecklistItemsListener
23+
import com.simplemobiletools.notes.pro.interfaces.ItemMoveCallback
24+
import com.simplemobiletools.notes.pro.interfaces.ItemTouchHelperContract
25+
import com.simplemobiletools.notes.pro.interfaces.StartReorderDragListener
2026
import com.simplemobiletools.notes.pro.models.ChecklistItem
2127
import kotlinx.android.synthetic.main.item_checklist.view.*
2228
import java.util.*
2329

2430
class ChecklistAdapter(activity: BaseSimpleActivity, var items: ArrayList<ChecklistItem>, val listener: ChecklistItemsListener?,
2531
recyclerView: MyRecyclerView, val showIcons: Boolean, itemClick: (Any) -> Unit) :
26-
MyRecyclerViewAdapter(activity, recyclerView, null, itemClick) {
32+
MyRecyclerViewAdapter(activity, recyclerView, null, itemClick), ItemTouchHelperContract {
2733

2834
private lateinit var crossDrawable: Drawable
2935
private lateinit var checkDrawable: Drawable
36+
private var touchHelper: ItemTouchHelper? = null
37+
private var startReorderDragListener: StartReorderDragListener
3038

3139
init {
3240
setupDragListener(true)
3341
initDrawables()
42+
43+
touchHelper = ItemTouchHelper(ItemMoveCallback(this))
44+
touchHelper!!.attachToRecyclerView(recyclerView)
45+
46+
startReorderDragListener = object : StartReorderDragListener {
47+
override fun requestDrag(viewHolder: RecyclerView.ViewHolder) {
48+
touchHelper?.startDrag(viewHolder)
49+
}
50+
}
3451
}
3552

3653
override fun getActionMenuId() = R.menu.cab_checklist
@@ -76,7 +93,7 @@ class ChecklistAdapter(activity: BaseSimpleActivity, var items: ArrayList<Checkl
7693
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
7794
val item = items[position]
7895
holder.bindView(item, true, true) { itemView, layoutPosition ->
79-
setupView(itemView, item)
96+
setupView(itemView, item, holder)
8097
}
8198
bindViewHolder(holder)
8299
}
@@ -130,7 +147,7 @@ class ChecklistAdapter(activity: BaseSimpleActivity, var items: ArrayList<Checkl
130147

131148
private fun getSelectedItems() = items.filter { selectedKeys.contains(it.id) } as ArrayList<ChecklistItem>
132149

133-
private fun setupView(view: View, checklistItem: ChecklistItem) {
150+
private fun setupView(view: View, checklistItem: ChecklistItem, holder: ViewHolder) {
134151
val isSelected = selectedKeys.contains(checklistItem.id)
135152
view.apply {
136153
checklist_title.apply {
@@ -149,10 +166,36 @@ class ChecklistAdapter(activity: BaseSimpleActivity, var items: ArrayList<Checkl
149166

150167
checklist_image.setImageDrawable(if (checklistItem.isDone) checkDrawable else crossDrawable)
151168
checklist_image.beVisibleIf(showIcons)
169+
checklist_holder.isSelected = isSelected
152170

153171
checklist_drag_handle.beVisibleIf(selectedKeys.isNotEmpty())
154172
checklist_drag_handle.applyColorFilter(textColor)
155-
checklist_holder.isSelected = isSelected
173+
checklist_drag_handle.setOnTouchListener { v, event ->
174+
if (event.action == MotionEvent.ACTION_DOWN) {
175+
startReorderDragListener.requestDrag(holder)
176+
}
177+
false
178+
}
179+
}
180+
}
181+
182+
override fun onRowMoved(fromPosition: Int, toPosition: Int) {
183+
if (fromPosition < toPosition) {
184+
for (i in fromPosition until toPosition) {
185+
Collections.swap(items, i, i + 1)
186+
}
187+
} else {
188+
for (i in fromPosition downTo toPosition + 1) {
189+
Collections.swap(items, i, i - 1)
190+
}
156191
}
192+
notifyItemMoved(fromPosition, toPosition)
193+
}
194+
195+
override fun onRowSelected(myViewHolder: ViewHolder?) {
196+
}
197+
198+
override fun onRowClear(myViewHolder: ViewHolder?) {
199+
listener?.saveChecklist()
157200
}
158201
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.simplemobiletools.notes.pro.interfaces
2+
3+
import androidx.recyclerview.widget.ItemTouchHelper
4+
import androidx.recyclerview.widget.RecyclerView
5+
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
6+
7+
open class ItemMoveCallback(private val mAdapter: ItemTouchHelperContract) : ItemTouchHelper.Callback() {
8+
override fun isLongPressDragEnabled() = false
9+
10+
override fun isItemViewSwipeEnabled() = false
11+
12+
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, i: Int) {}
13+
14+
override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
15+
val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
16+
return makeMovementFlags(dragFlags, 0)
17+
}
18+
19+
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
20+
mAdapter.onRowMoved(viewHolder.adapterPosition, target.adapterPosition)
21+
return true
22+
}
23+
24+
override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
25+
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
26+
if (viewHolder is MyRecyclerViewAdapter.ViewHolder) {
27+
mAdapter.onRowSelected(viewHolder)
28+
}
29+
}
30+
super.onSelectedChanged(viewHolder, actionState)
31+
}
32+
33+
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
34+
super.clearView(recyclerView, viewHolder)
35+
if (viewHolder is MyRecyclerViewAdapter.ViewHolder) {
36+
mAdapter.onRowClear(viewHolder)
37+
}
38+
}
39+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.simplemobiletools.notes.pro.interfaces
2+
3+
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
4+
5+
interface ItemTouchHelperContract {
6+
fun onRowMoved(fromPosition: Int, toPosition: Int)
7+
8+
fun onRowSelected(myViewHolder: MyRecyclerViewAdapter.ViewHolder?)
9+
10+
fun onRowClear(myViewHolder: MyRecyclerViewAdapter.ViewHolder?)
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.simplemobiletools.notes.pro.interfaces
2+
3+
import androidx.recyclerview.widget.RecyclerView
4+
5+
interface StartReorderDragListener {
6+
fun requestDrag(viewHolder: RecyclerView.ViewHolder)
7+
}

0 commit comments

Comments
 (0)