@@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable
55import android.net.Uri
66import android.support.v7.view.ActionMode
77import android.support.v7.widget.RecyclerView
8+ import android.util.SparseArray
89import android.view.*
910import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
1011import com.bignerdranch.android.multiselector.MultiSelector
@@ -28,42 +29,53 @@ import java.util.*
2829
2930class 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}
0 commit comments