refactor ItemsAdapter
This commit is contained in:
parent
8c9f7bf050
commit
dc595c5a0e
|
@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.support.v7.view.ActionMode
|
import android.support.v7.view.ActionMode
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.util.SparseArray
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
|
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback
|
||||||
import com.bignerdranch.android.multiselector.MultiSelector
|
import com.bignerdranch.android.multiselector.MultiSelector
|
||||||
|
@ -28,42 +29,53 @@ import java.util.*
|
||||||
|
|
||||||
class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDirItem>, val listener: ItemOperationsListener?, val itemClick: (FileDirItem) -> Unit) :
|
class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDirItem>, val listener: ItemOperationsListener?, val itemClick: (FileDirItem) -> Unit) :
|
||||||
RecyclerView.Adapter<ItemsAdapter.ViewHolder>() {
|
RecyclerView.Adapter<ItemsAdapter.ViewHolder>() {
|
||||||
|
|
||||||
val multiSelector = MultiSelector()
|
val multiSelector = MultiSelector()
|
||||||
val views = ArrayList<View>()
|
|
||||||
val config = activity.config
|
val config = activity.config
|
||||||
|
|
||||||
companion object {
|
var actMode: ActionMode? = null
|
||||||
var actMode: ActionMode? = null
|
var itemViews = SparseArray<View>()
|
||||||
val markedItems = HashSet<Int>()
|
val selectedPositions = HashSet<Int>()
|
||||||
var textColor = 0
|
|
||||||
var itemCnt = 0
|
|
||||||
|
|
||||||
lateinit var folderDrawable: Drawable
|
var textColor = activity.config.textColor
|
||||||
lateinit var fileDrawable: Drawable
|
|
||||||
|
|
||||||
fun toggleItemSelection(itemView: View, select: Boolean, pos: Int = -1) {
|
lateinit var folderDrawable: Drawable
|
||||||
itemView.item_frame.isSelected = select
|
lateinit var fileDrawable: Drawable
|
||||||
if (pos == -1)
|
|
||||||
return
|
|
||||||
|
|
||||||
if (select)
|
fun toggleItemSelection(select: Boolean, pos: Int) {
|
||||||
markedItems.add(pos)
|
itemViews[pos]?.item_frame?.isSelected = select
|
||||||
else
|
|
||||||
markedItems.remove(pos)
|
if (select)
|
||||||
|
selectedPositions.add(pos)
|
||||||
|
else
|
||||||
|
selectedPositions.remove(pos)
|
||||||
|
|
||||||
|
if (selectedPositions.isEmpty()) {
|
||||||
|
actMode?.finish()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateTitle(cnt: Int) {
|
updateTitle(selectedPositions.size)
|
||||||
actMode?.title = "$cnt / $itemCnt"
|
actMode?.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateTitle(cnt: Int) {
|
||||||
|
actMode?.title = "$cnt / ${mItems.size}"
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
textColor = activity.config.textColor
|
folderDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_folder, textColor)
|
||||||
folderDrawable = activity.resources.getColoredDrawableWithColor(com.simplemobiletools.commons.R.drawable.ic_folder, textColor)
|
|
||||||
folderDrawable.alpha = 180
|
folderDrawable.alpha = 180
|
||||||
fileDrawable = activity.resources.getColoredDrawableWithColor(com.simplemobiletools.commons.R.drawable.ic_file, textColor)
|
fileDrawable = activity.resources.getColoredDrawableWithColor(R.drawable.ic_file, textColor)
|
||||||
fileDrawable.alpha = 180
|
fileDrawable.alpha = 180
|
||||||
itemCnt = mItems.size
|
}
|
||||||
|
|
||||||
|
val adapterListener = object : MyAdapterListener {
|
||||||
|
override fun toggleItemSelectionAdapter(select: Boolean, position: Int) {
|
||||||
|
toggleItemSelection(select, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSelectedPositions(): HashSet<Int> = selectedPositions
|
||||||
}
|
}
|
||||||
|
|
||||||
val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
|
val multiSelectorMode = object : ModalMultiSelectorCallback(multiSelector) {
|
||||||
|
@ -89,14 +101,16 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
|
||||||
|
|
||||||
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
|
override fun onPrepareActionMode(actionMode: ActionMode?, menu: Menu): Boolean {
|
||||||
val menuItem = menu.findItem(R.id.cab_rename)
|
val menuItem = menu.findItem(R.id.cab_rename)
|
||||||
menuItem.isVisible = multiSelector.selectedPositions.size <= 1
|
menuItem.isVisible = selectedPositions.size <= 1
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyActionMode(actionMode: ActionMode?) {
|
override fun onDestroyActionMode(actionMode: ActionMode?) {
|
||||||
super.onDestroyActionMode(actionMode)
|
super.onDestroyActionMode(actionMode)
|
||||||
views.forEach { toggleItemSelection(it, false) }
|
selectedPositions.forEach {
|
||||||
markedItems.clear()
|
itemViews[it]?.isSelected = false
|
||||||
|
}
|
||||||
|
selectedPositions.clear()
|
||||||
actMode = null
|
actMode = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,12 +125,11 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showProperties() {
|
private fun showProperties() {
|
||||||
val selections = multiSelector.selectedPositions
|
if (selectedPositions.size <= 1) {
|
||||||
if (selections.size <= 1) {
|
PropertiesDialog(activity, mItems[selectedPositions.first()].path, config.showHidden)
|
||||||
PropertiesDialog(activity, mItems[selections[0]].path, config.showHidden)
|
|
||||||
} else {
|
} else {
|
||||||
val paths = ArrayList<String>()
|
val paths = ArrayList<String>()
|
||||||
selections.forEach { paths.add(mItems[it].path) }
|
selectedPositions.forEach { paths.add(mItems[it].path) }
|
||||||
PropertiesDialog(activity, paths, config.showHidden)
|
PropertiesDialog(activity, paths, config.showHidden)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,8 +155,7 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
|
||||||
|
|
||||||
private fun copyMoveTo(isCopyOperation: Boolean) {
|
private fun copyMoveTo(isCopyOperation: Boolean) {
|
||||||
val files = ArrayList<File>()
|
val files = ArrayList<File>()
|
||||||
val positions = multiSelector.selectedPositions
|
selectedPositions.forEach { files.add(File(mItems[it].path)) }
|
||||||
positions.forEach { files.add(File(mItems[it].path)) }
|
|
||||||
|
|
||||||
val source = if (files[0].isFile) files[0].parent else files[0].absolutePath
|
val source = if (files[0].isFile) files[0].parent else files[0].absolutePath
|
||||||
FilePickerDialog(activity, source, false, config.showHidden, true) {
|
FilePickerDialog(activity, source, false, config.showHidden, true) {
|
||||||
|
@ -158,36 +170,47 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
|
||||||
|
|
||||||
private fun askConfirmDelete() {
|
private fun askConfirmDelete() {
|
||||||
ConfirmationDialog(activity) {
|
ConfirmationDialog(activity) {
|
||||||
actMode?.finish()
|
|
||||||
deleteFiles()
|
deleteFiles()
|
||||||
|
actMode?.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deleteFiles() {
|
private fun deleteFiles() {
|
||||||
val selections = multiSelector.selectedPositions
|
if (selectedPositions.isEmpty())
|
||||||
val files = ArrayList<File>(selections.size)
|
return
|
||||||
val removeFiles = ArrayList<FileDirItem>(selections.size)
|
|
||||||
|
|
||||||
activity.handleSAFDialog(File(mItems[selections[0]].path)) {
|
val files = ArrayList<File>(selectedPositions.size)
|
||||||
selections.reverse()
|
val removeFiles = ArrayList<FileDirItem>(selectedPositions.size)
|
||||||
selections.forEach {
|
|
||||||
|
activity.handleSAFDialog(File(mItems[selectedPositions.first()].path)) {
|
||||||
|
selectedPositions.sortedDescending().forEach {
|
||||||
val file = mItems[it]
|
val file = mItems[it]
|
||||||
files.add(File(file.path))
|
files.add(File(file.path))
|
||||||
removeFiles.add(file)
|
removeFiles.add(file)
|
||||||
notifyItemRemoved(it)
|
notifyItemRemoved(it)
|
||||||
|
itemViews.put(it, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
mItems.removeAll(removeFiles)
|
mItems.removeAll(removeFiles)
|
||||||
markedItems.clear()
|
selectedPositions.clear()
|
||||||
listener?.deleteFiles(files)
|
listener?.deleteFiles(files)
|
||||||
itemCnt = mItems.size
|
|
||||||
|
val newItems = SparseArray<View>()
|
||||||
|
var curIndex = 0
|
||||||
|
for (i in 0..itemViews.size() - 1) {
|
||||||
|
if (itemViews[i] != null) {
|
||||||
|
newItems.put(curIndex, itemViews[i])
|
||||||
|
curIndex++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
itemViews = newItems
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSelectedMedia(): List<FileDirItem> {
|
private fun getSelectedMedia(): List<FileDirItem> {
|
||||||
val positions = multiSelector.selectedPositions
|
val selectedMedia = ArrayList<FileDirItem>(selectedPositions.size)
|
||||||
val selectedMedia = ArrayList<FileDirItem>(positions.size)
|
selectedPositions.forEach { selectedMedia.add(mItems[it]) }
|
||||||
positions.forEach { selectedMedia.add(mItems[it]) }
|
|
||||||
return selectedMedia
|
return selectedMedia
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,11 +221,13 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
|
||||||
val view = LayoutInflater.from(parent?.context).inflate(R.layout.list_item, parent, false)
|
val view = LayoutInflater.from(parent?.context).inflate(R.layout.list_item, parent, false)
|
||||||
return ViewHolder(activity, view, itemClick)
|
return ViewHolder(view, adapterListener, activity, multiSelectorMode, multiSelector, listener, itemClick)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
views.add(holder.bindView(multiSelectorMode, multiSelector, mItems[position], position))
|
itemViews.put(position, holder.bindView(mItems[position], fileDrawable, folderDrawable, textColor))
|
||||||
|
toggleItemSelection(selectedPositions.contains(position), position)
|
||||||
|
holder.itemView.tag = holder
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewRecycled(holder: ViewHolder?) {
|
override fun onViewRecycled(holder: ViewHolder?) {
|
||||||
|
@ -212,14 +237,15 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
|
||||||
|
|
||||||
override fun getItemCount() = mItems.size
|
override fun getItemCount() = mItems.size
|
||||||
|
|
||||||
class ViewHolder(val activity: SimpleActivity, val view: View, val itemClick: (FileDirItem) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
|
class ViewHolder(val view: View, val adapterListener: MyAdapterListener, val activity: SimpleActivity, val multiSelectorCallback: ModalMultiSelectorCallback,
|
||||||
fun bindView(multiSelectorCallback: ModalMultiSelectorCallback, multiSelector: MultiSelector, fileDirItem: FileDirItem, pos: Int): View {
|
val multiSelector: MultiSelector, val listener: ItemOperationsListener?, val itemClick: (FileDirItem) -> (Unit)) : SwappingHolder(view, MultiSelector()) {
|
||||||
|
fun bindView(fileDirItem: FileDirItem, fileDrawable: Drawable, folderDrawable: Drawable, textColor: Int): View {
|
||||||
itemView.apply {
|
itemView.apply {
|
||||||
item_name.text = fileDirItem.name
|
item_name.text = fileDirItem.name
|
||||||
item_name.setTextColor(textColor)
|
item_name.setTextColor(textColor)
|
||||||
item_details.setTextColor(textColor)
|
item_details.setTextColor(textColor)
|
||||||
|
|
||||||
toggleItemSelection(this, markedItems.contains(pos), pos)
|
// toggleItemSelection(this, selectedPositions.contains(pos), pos)
|
||||||
|
|
||||||
if (fileDirItem.isDirectory) {
|
if (fileDirItem.isDirectory) {
|
||||||
item_icon.setImageDrawable(folderDrawable)
|
item_icon.setImageDrawable(folderDrawable)
|
||||||
|
@ -230,17 +256,8 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
|
||||||
item_details.text = fileDirItem.size.formatSize()
|
item_details.text = fileDirItem.size.formatSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
setOnClickListener { viewClicked(multiSelector, fileDirItem, pos) }
|
setOnClickListener { viewClicked(fileDirItem) }
|
||||||
setOnLongClickListener {
|
setOnLongClickListener { viewLongClicked(); true }
|
||||||
if (!multiSelector.isSelectable) {
|
|
||||||
activity.startSupportActionMode(multiSelectorCallback)
|
|
||||||
multiSelector.setSelected(this@ViewHolder, true)
|
|
||||||
updateTitle(multiSelector.selectedPositions.size)
|
|
||||||
toggleItemSelection(this, true, pos)
|
|
||||||
actMode?.invalidate()
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemView
|
return itemView
|
||||||
|
@ -251,32 +268,42 @@ class ItemsAdapter(val activity: SimpleActivity, var mItems: MutableList<FileDir
|
||||||
return activity.resources.getQuantityString(R.plurals.items, children, children)
|
return activity.resources.getQuantityString(R.plurals.items, children, children)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun viewClicked(multiSelector: MultiSelector, fileDirItem: FileDirItem, pos: Int) {
|
fun viewClicked(fileDirItem: FileDirItem) {
|
||||||
if (multiSelector.isSelectable) {
|
if (multiSelector.isSelectable) {
|
||||||
val isSelected = multiSelector.selectedPositions.contains(layoutPosition)
|
val isSelected = adapterListener.getSelectedPositions().contains(layoutPosition)
|
||||||
multiSelector.setSelected(this, !isSelected)
|
adapterListener.toggleItemSelectionAdapter(!isSelected, layoutPosition)
|
||||||
toggleItemSelection(itemView, !isSelected, pos)
|
|
||||||
|
|
||||||
val selectedCnt = multiSelector.selectedPositions.size
|
|
||||||
if (selectedCnt == 0) {
|
|
||||||
actMode?.finish()
|
|
||||||
} else {
|
|
||||||
updateTitle(selectedCnt)
|
|
||||||
}
|
|
||||||
actMode?.invalidate()
|
|
||||||
} else {
|
} else {
|
||||||
itemClick(fileDirItem)
|
itemClick(fileDirItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun viewLongClicked() {
|
||||||
|
if (listener != null) {
|
||||||
|
if (!multiSelector.isSelectable) {
|
||||||
|
activity.startSupportActionMode(multiSelectorCallback)
|
||||||
|
adapterListener.toggleItemSelectionAdapter(true, layoutPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
listener.itemLongClicked(layoutPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun stopLoad() {
|
fun stopLoad() {
|
||||||
Glide.clear(view.item_icon)
|
Glide.clear(view.item_icon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MyAdapterListener {
|
||||||
|
fun toggleItemSelectionAdapter(select: Boolean, position: Int)
|
||||||
|
|
||||||
|
fun getSelectedPositions(): HashSet<Int>
|
||||||
|
}
|
||||||
|
|
||||||
interface ItemOperationsListener {
|
interface ItemOperationsListener {
|
||||||
fun refreshItems()
|
fun refreshItems()
|
||||||
|
|
||||||
fun deleteFiles(files: ArrayList<File>)
|
fun deleteFiles(files: ArrayList<File>)
|
||||||
|
|
||||||
|
fun itemLongClicked(position: Int)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,10 @@ class ItemsFragment : android.support.v4.app.Fragment(), ItemsAdapter.ItemOperat
|
||||||
return "$type/*"
|
return "$type/*"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun refreshItems() {
|
||||||
|
fillItems()
|
||||||
|
}
|
||||||
|
|
||||||
override fun deleteFiles(files: ArrayList<File>) {
|
override fun deleteFiles(files: ArrayList<File>) {
|
||||||
val hasFolder = files.any { it.isDirectory }
|
val hasFolder = files.any { it.isDirectory }
|
||||||
(activity as SimpleActivity).deleteFiles(files, hasFolder) {
|
(activity as SimpleActivity).deleteFiles(files, hasFolder) {
|
||||||
|
@ -214,8 +218,8 @@ class ItemsFragment : android.support.v4.app.Fragment(), ItemsAdapter.ItemOperat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun refreshItems() {
|
override fun itemLongClicked(position: Int) {
|
||||||
fillItems()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ItemInteractionListener {
|
interface ItemInteractionListener {
|
||||||
|
|
Loading…
Reference in New Issue