Skip to content

Commit dc595c5

Browse files
committed
refactor ItemsAdapter
1 parent 8c9f7bf commit dc595c5

File tree

2 files changed

+105
-74
lines changed

2 files changed

+105
-74
lines changed

app/src/main/kotlin/com/simplemobiletools/filemanager/adapters/ItemsAdapter.kt

Lines changed: 99 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable
55
import android.net.Uri
66
import android.support.v7.view.ActionMode
77
import android.support.v7.widget.RecyclerView
8+
import android.util.SparseArray
89
import android.view.*
910
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
1011
import com.bignerdranch.android.multiselector.MultiSelector
@@ -28,42 +29,53 @@ import java.util.*
2829

2930
class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDirItem>, val listener: ItemOperationsListener?, val itemClick: (FileDirItem) -> Unit) :
3031
RecyclerView.Adapter<ItemsAdapter.ViewHolder>() {
32+
3133
val multiSelector = MultiSelector()
32-
val views = ArrayList<View>()
3334
val config = activity.config
3435

35-
companion object {
36-
var actMode: ActionMode? = null
37-
val markedItems = HashSet<Int>()
38-
var textColor = 0
39-
var itemCnt = 0
36+
var actMode: ActionMode? = null
37+
var itemViews = SparseArray<View>()
38+
val selectedPositions = HashSet<Int>()
4039

41-
lateinit var folderDrawable: Drawable
42-
lateinit var fileDrawable: Drawable
40+
var textColor = activity.config.textColor
4341

44-
fun toggleItemSelection(itemView: View, select: Boolean, pos: Int = -1) {
45-
itemView.item_frame.isSelected = select
46-
if (pos == -1)
47-
return
42+
lateinit var folderDrawable: Drawable
43+
lateinit var fileDrawable: Drawable
4844

49-
if (select)
50-
markedItems.add(pos)
51-
else
52-
markedItems.remove(pos)
53-
}
45+
fun toggleItemSelection(select: Boolean, pos: Int) {
46+
itemViews[pos]?.item_frame?.isSelected = select
47+
48+
if (select)
49+
selectedPositions.add(pos)
50+
else
51+
selectedPositions.remove(pos)
5452

55-
fun updateTitle(cnt: Int) {
56-
actMode?.title = "$cnt / $itemCnt"
53+
if (selectedPositions.isEmpty()) {
54+
actMode?.finish()
55+
return
5756
}
57+
58+
updateTitle(selectedPositions.size)
59+
actMode?.invalidate()
60+
}
61+
62+
fun updateTitle(cnt: Int) {
63+
actMode?.title = "$cnt / ${mItems.size}"
5864
}
5965

6066
init {
61-
textColor = activity.config.textColor
62-
folderDrawable = activity.resources.getColoredDrawableWithColor(com.simplemobiletools.commons.R.drawable.ic_folder, textColor)
67+
folderDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_folder, textColor)
6368
folderDrawable.alpha = 180
64-
fileDrawable = activity.resources.getColoredDrawableWithColor(com.simplemobiletools.commons.R.drawable.ic_file, textColor)
69+
fileDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_file, textColor)
6570
fileDrawable.alpha = 180
66-
itemCnt = mItems.size
71+
}
72+
73+
val adapterListener = object : MyAdapterListener {
74+
override fun toggleItemSelectionAdapter(select: Boolean, position: Int) {
75+
toggleItemSelection(select, position)
76+
}
77+
78+
override fun getSelectedPositions(): HashSet<Int> = selectedPositions
6779
}
6880

6981
val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
@@ -89,14 +101,16 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
89101

90102
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
91103
val menuItem = menu.findItem(R.id.cab_rename)
92-
menuItem.isVisible = multiSelector.selectedPositions.size <= 1
104+
menuItem.isVisible = selectedPositions.size <= 1
93105
return true
94106
}
95107

96108
override fun onDestroyActionMode(actionMode: ActionMode?) {
97109
super.onDestroyActionMode(actionMode)
98-
views.forEach { toggleItemSelection(it, false) }
99-
markedItems.clear()
110+
selectedPositions.forEach {
111+
itemViews[it]?.isSelected = false
112+
}
113+
selectedPositions.clear()
100114
actMode = null
101115
}
102116
}
@@ -111,12 +125,11 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
111125
}
112126

113127
private fun showProperties() {
114-
val selections = multiSelector.selectedPositions
115-
if (selections.size <= 1) {
116-
PropertiesDialog(activity, mItems[selections[0]].path, config.showHidden)
128+
if (selectedPositions.size <= 1) {
129+
PropertiesDialog(activity, mItems[selectedPositions.first()].path, config.showHidden)
117130
} else {
118131
val paths = ArrayList<String>()
119-
selections.forEach { paths.add(mItems[it].path) }
132+
selectedPositions.forEach { paths.add(mItems[it].path) }
120133
PropertiesDialog(activity, paths, config.showHidden)
121134
}
122135
}
@@ -142,8 +155,7 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
142155

143156
private fun copyMoveTo(isCopyOperation: Boolean) {
144157
val files = ArrayList<File>()
145-
val positions = multiSelector.selectedPositions
146-
positions.forEach { files.add(File(mItems[it].path)) }
158+
selectedPositions.forEach { files.add(File(mItems[it].path)) }
147159

148160
val source = if (files[0].isFile) files[0].parent else files[0].absolutePath
149161
FilePickerDialog(activity, source, false, config.showHidden, true) {
@@ -158,36 +170,47 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
158170

159171
private fun askConfirmDelete() {
160172
ConfirmationDialog(activity) {
161-
actMode?.finish()
162173
deleteFiles()
174+
actMode?.finish()
163175
}
164176
}
165177

166178
private fun deleteFiles() {
167-
val selections = multiSelector.selectedPositions
168-
val files = ArrayList<File>(selections.size)
169-
val removeFiles = ArrayList<FileDirItem>(selections.size)
179+
if (selectedPositions.isEmpty())
180+
return
181+
182+
val files = ArrayList<File>(selectedPositions.size)
183+
val removeFiles = ArrayList<FileDirItem>(selectedPositions.size)
170184

171-
activity.handleSAFDialog(File(mItems[selections[0]].path)) {
172-
selections.reverse()
173-
selections.forEach {
185+
activity.handleSAFDialog(File(mItems[selectedPositions.first()].path)) {
186+
selectedPositions.sortedDescending().forEach {
174187
val file = mItems[it]
175188
files.add(File(file.path))
176189
removeFiles.add(file)
177190
notifyItemRemoved(it)
191+
itemViews.put(it, null)
178192
}
179193

180194
mItems.removeAll(removeFiles)
181-
markedItems.clear()
195+
selectedPositions.clear()
182196
listener?.deleteFiles(files)
183-
itemCnt = mItems.size
197+
198+
val newItems = SparseArray<View>()
199+
var curIndex = 0
200+
for (i in 0..itemViews.size() - 1) {
201+
if (itemViews[i] != null) {
202+
newItems.put(curIndex, itemViews[i])
203+
curIndex++
204+
}
205+
}
206+
207+
itemViews = newItems
184208
}
185209
}
186210

187211
private fun getSelectedMedia(): List<FileDirItem> {
188-
val positions = multiSelector.selectedPositions
189-
val selectedMedia = ArrayList<FileDirItem>(positions.size)
190-
positions.forEach { selectedMedia.add(mItems[it]) }
212+
val selectedMedia = ArrayList<FileDirItem>(selectedPositions.size)
213+
selectedPositions.forEach { selectedMedia.add(mItems[it]) }
191214
return selectedMedia
192215
}
193216

@@ -198,11 +221,13 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
198221

199222
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
200223
val view = LayoutInflater.from(parent?.context).inflate(R.layout.list_item, parent, false)
201-
return ViewHolder(activity, view, itemClick)
224+
return ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, listener, itemClick)
202225
}
203226

204227
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
205-
views.add(holder.bindView(multiSelectorMode, multiSelector, mItems[position], position))
228+
itemViews.put(position, holder.bindView(mItems[position], fileDrawable, folderDrawable, textColor))
229+
toggleItemSelection(selectedPositions.contains(position), position)
230+
holder.itemView.tag = holder
206231
}
207232

208233
override fun onViewRecycled(holder: ViewHolder?) {
@@ -212,14 +237,15 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
212237

213238
override fun getItemCount() = mItems.size
214239

215-
class ViewHolder(val activity: SimpleActivity, val view: View, val itemClick: (FileDirItem) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
216-
fun bindView(multiSelectorCallback: ModalMultiSelectorCallback, multiSelector: MultiSelector, fileDirItem: FileDirItem, pos: Int): View {
240+
class ViewHolder(val view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback,
241+
val multiSelector: MultiSelector, val listener: ItemOperationsListener?, val itemClick: (FileDirItem) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
242+
fun bindView(fileDirItem: FileDirItem, fileDrawable: Drawable, folderDrawable: Drawable, textColor: Int): View {
217243
itemView.apply {
218244
item_name.text = fileDirItem.name
219245
item_name.setTextColor(textColor)
220246
item_details.setTextColor(textColor)
221247

222-
toggleItemSelection(this, markedItems.contains(pos), pos)
248+
// toggleItemSelection(this, selectedPositions.contains(pos), pos)
223249

224250
if (fileDirItem.isDirectory) {
225251
item_icon.setImageDrawable(folderDrawable)
@@ -230,17 +256,8 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
230256
item_details.text = fileDirItem.size.formatSize()
231257
}
232258

233-
setOnClickListener { viewClicked(multiSelector, fileDirItem, pos) }
234-
setOnLongClickListener {
235-
if (!multiSelector.isSelectable) {
236-
activity.startSupportActionMode(multiSelectorCallback)
237-
multiSelector.setSelected(this@ViewHolder, true)
238-
updateTitle(multiSelector.selectedPositions.size)
239-
toggleItemSelection(this, true, pos)
240-
actMode?.invalidate()
241-
}
242-
true
243-
}
259+
setOnClickListener { viewClicked(fileDirItem) }
260+
setOnLongClickListener { viewLongClicked(); true }
244261
}
245262

246263
return itemView
@@ -251,32 +268,42 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
251268
return activity.resources.getQuantityString(R.plurals.items, children, children)
252269
}
253270

254-
fun viewClicked(multiSelector: MultiSelector, fileDirItem: FileDirItem, pos: Int) {
271+
fun viewClicked(fileDirItem: FileDirItem) {
255272
if (multiSelector.isSelectable) {
256-
val isSelected = multiSelector.selectedPositions.contains(layoutPosition)
257-
multiSelector.setSelected(this, !isSelected)
258-
toggleItemSelection(itemView, !isSelected, pos)
259-
260-
val selectedCnt = multiSelector.selectedPositions.size
261-
if (selectedCnt == 0) {
262-
actMode?.finish()
263-
} else {
264-
updateTitle(selectedCnt)
265-
}
266-
actMode?.invalidate()
273+
val isSelected = adapterListener.getSelectedPositions().contains(layoutPosition)
274+
adapterListener.toggleItemSelectionAdapter(!isSelected, layoutPosition)
267275
} else {
268276
itemClick(fileDirItem)
269277
}
270278
}
271279

280+
fun viewLongClicked() {
281+
if (listener != null) {
282+
if (!multiSelector.isSelectable) {
283+
activity.startSupportActionMode(multiSelectorCallback)
284+
adapterListener.toggleItemSelectionAdapter(true, layoutPosition)
285+
}
286+
287+
listener.itemLongClicked(layoutPosition)
288+
}
289+
}
290+
272291
fun stopLoad() {
273292
Glide.clear(view.item_icon)
274293
}
275294
}
276295

296+
interface MyAdapterListener {
297+
fun toggleItemSelectionAdapter(select: Boolean, position: Int)
298+
299+
fun getSelectedPositions(): HashSet<Int>
300+
}
301+
277302
interface ItemOperationsListener {
278303
fun refreshItems()
279304

280305
fun deleteFiles(files: ArrayList<File>)
306+
307+
fun itemLongClicked(position: Int)
281308
}
282309
}

app/src/main/kotlin/com/simplemobiletools/filemanager/fragments/ItemsFragment.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ class ItemsFragment : android.support.v4.app.Fragment(), ItemsAdapter.ItemOperat
203203
return "$type/*"
204204
}
205205

206+
override fun refreshItems() {
207+
fillItems()
208+
}
209+
206210
override fun deleteFiles(files: ArrayList<File>) {
207211
val hasFolder = files.any { it.isDirectory }
208212
(activity as SimpleActivity).deleteFiles(files, hasFolder) {
@@ -214,8 +218,8 @@ class ItemsFragment : android.support.v4.app.Fragment(), ItemsAdapter.ItemOperat
214218
}
215219
}
216220

217-
override fun refreshItems() {
218-
fillItems()
221+
override fun itemLongClicked(position: Int) {
222+
219223
}
220224

221225
interface ItemInteractionListener {

0 commit comments

Comments
 (0)