forked from hardcoresushi/DroidFS
Refactor RecyclerView adapters
This commit is contained in:
parent
4de5b41102
commit
f541504e07
@ -22,7 +22,6 @@ import sushi.hardcore.droidfs.explorers.ExplorerElement
|
||||
import sushi.hardcore.droidfs.util.PathUtils
|
||||
import java.text.DateFormat
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
|
||||
class ExplorerElementAdapter(
|
||||
val activity: AppCompatActivity,
|
||||
@ -30,7 +29,7 @@ class ExplorerElementAdapter(
|
||||
val onExplorerElementClick: (Int) -> Unit,
|
||||
val onExplorerElementLongClick: (Int) -> Unit,
|
||||
val thumbnailMaxSize: Long,
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
) : SelectableAdapter<ExplorerElement>() {
|
||||
val dateFormat: DateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.getDefault())
|
||||
var explorerElements = listOf<ExplorerElement>()
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
@ -39,7 +38,6 @@ class ExplorerElementAdapter(
|
||||
thumbnailsCache?.evictAll()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
var selectedItems: MutableSet<Int> = HashSet()
|
||||
var isUsingListLayout = true
|
||||
private var thumbnailsCache: LruCache<String, Bitmap>? = null
|
||||
|
||||
@ -49,54 +47,30 @@ class ExplorerElementAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return explorerElements.size
|
||||
override fun getItems(): List<ExplorerElement> {
|
||||
return explorerElements
|
||||
}
|
||||
|
||||
private fun toggleSelection(position: Int): Boolean {
|
||||
if (!explorerElements[position].isParentFolder) {
|
||||
if (selectedItems.contains(position)) {
|
||||
selectedItems.remove(position)
|
||||
override fun toggleSelection(position: Int): Boolean {
|
||||
return if (!explorerElements[position].isParentFolder) {
|
||||
super.toggleSelection(position)
|
||||
} else {
|
||||
selectedItems.add(position)
|
||||
return true
|
||||
false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun onItemClick(position: Int): Boolean {
|
||||
override fun onItemClick(position: Int): Boolean {
|
||||
onExplorerElementClick(position)
|
||||
if (selectedItems.isNotEmpty()) {
|
||||
return toggleSelection(position)
|
||||
}
|
||||
return false
|
||||
return super.onItemClick(position)
|
||||
}
|
||||
|
||||
private fun onItemLongClick(position: Int): Boolean {
|
||||
override fun onItemLongClick(position: Int): Boolean {
|
||||
onExplorerElementLongClick(position)
|
||||
return toggleSelection(position)
|
||||
return super.onItemLongClick(position)
|
||||
}
|
||||
|
||||
fun selectAll() {
|
||||
for (i in explorerElements.indices) {
|
||||
if (!selectedItems.contains(i) && !explorerElements[i].isParentFolder) {
|
||||
selectedItems.add(i)
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun unSelectAll(notifyChange: Boolean) {
|
||||
if (notifyChange) {
|
||||
val whatWasSelected = selectedItems
|
||||
selectedItems = HashSet()
|
||||
whatWasSelected.forEach {
|
||||
notifyItemChanged(it)
|
||||
}
|
||||
} else {
|
||||
selectedItems.clear()
|
||||
}
|
||||
override fun isSelectable(position: Int): Boolean {
|
||||
return !explorerElements[position].isParentFolder
|
||||
}
|
||||
|
||||
open class ExplorerElementViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
@ -116,21 +90,9 @@ class ExplorerElementAdapter(
|
||||
itemView.findViewById(R.id.selectable_container)
|
||||
}
|
||||
|
||||
protected fun setBackground(isSelected: Boolean) {
|
||||
itemView.setBackgroundResource(if (isSelected) { R.color.itemSelected } else { 0 })
|
||||
}
|
||||
|
||||
open fun bind(explorerElement: ExplorerElement, position: Int) {
|
||||
textElementName.text = explorerElement.name
|
||||
(bindingAdapter as ExplorerElementAdapter?)?.let { adapter ->
|
||||
selectableContainer.setOnClickListener {
|
||||
setBackground(adapter.onItemClick(position))
|
||||
}
|
||||
selectableContainer.setOnLongClickListener {
|
||||
setBackground(adapter.onItemLongClick(position))
|
||||
true
|
||||
}
|
||||
}
|
||||
(bindingAdapter as ExplorerElementAdapter?)?.setSelectable(selectableContainer, itemView, position)
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +103,6 @@ class ExplorerElementAdapter(
|
||||
(bindingAdapter as ExplorerElementAdapter?)?.let {
|
||||
textElementMtime.text = it.dateFormat.format(explorerElement.mTime)
|
||||
}
|
||||
setBackground(isSelected)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,76 @@
|
||||
package sushi.hardcore.droidfs.adapters
|
||||
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import sushi.hardcore.droidfs.R
|
||||
|
||||
abstract class SelectableAdapter<T> : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
var selectedItems: MutableSet<Int> = HashSet()
|
||||
|
||||
protected abstract fun getItems(): List<T>
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return getItems().size
|
||||
}
|
||||
|
||||
protected open fun toggleSelection(position: Int): Boolean {
|
||||
return if (selectedItems.contains(position)) {
|
||||
selectedItems.remove(position)
|
||||
false
|
||||
} else {
|
||||
selectedItems.add(position)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun onItemClick(position: Int): Boolean {
|
||||
if (selectedItems.isNotEmpty()) {
|
||||
return toggleSelection(position)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
protected open fun onItemLongClick(position: Int): Boolean {
|
||||
return toggleSelection(position)
|
||||
}
|
||||
|
||||
protected open fun isSelectable(position: Int): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
fun selectAll() {
|
||||
for (i in getItems().indices) {
|
||||
if (!selectedItems.contains(i) && isSelectable(i)) {
|
||||
selectedItems.add(i)
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun unSelectAll(notifyChange: Boolean) {
|
||||
if (notifyChange) {
|
||||
val whatWasSelected = selectedItems
|
||||
selectedItems = HashSet()
|
||||
whatWasSelected.forEach {
|
||||
notifyItemChanged(it)
|
||||
}
|
||||
} else {
|
||||
selectedItems.clear()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setBackground(rootView: View, isSelected: Boolean) {
|
||||
rootView.setBackgroundResource(if (isSelected) R.color.itemSelected else 0)
|
||||
}
|
||||
|
||||
protected fun setSelectable(element: View, rootView: View, position: Int) {
|
||||
element.setOnClickListener {
|
||||
setBackground(rootView, onItemClick(position))
|
||||
}
|
||||
element.setOnLongClickListener {
|
||||
setBackground(rootView, onItemLongClick(position))
|
||||
true
|
||||
}
|
||||
setBackground(rootView, selectedItems.contains(position))
|
||||
}
|
||||
}
|
@ -19,15 +19,18 @@ class VolumeAdapter(
|
||||
private val showReadOnly: Boolean,
|
||||
private val onVolumeItemClick: (Volume, Int) -> Unit,
|
||||
private val onVolumeItemLongClick: () -> Unit,
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
) : SelectableAdapter<Volume>() {
|
||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
lateinit var volumes: List<Volume>
|
||||
var selectedItems: MutableSet<Int> = HashSet()
|
||||
|
||||
init {
|
||||
reloadVolumes()
|
||||
}
|
||||
|
||||
override fun getItems(): List<Volume> {
|
||||
return volumes
|
||||
}
|
||||
|
||||
private fun reloadVolumes() {
|
||||
volumes = if (showReadOnly) {
|
||||
volumeDatabase.getVolumes()
|
||||
@ -36,28 +39,19 @@ class VolumeAdapter(
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleSelection(position: Int): Boolean {
|
||||
return if (selectedItems.contains(position)) {
|
||||
selectedItems.remove(position)
|
||||
false
|
||||
} else {
|
||||
selectedItems.add(position)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private fun onItemClick(position: Int): Boolean {
|
||||
override fun onItemClick(position: Int): Boolean {
|
||||
onVolumeItemClick(volumes[position], position)
|
||||
if (allowSelection && selectedItems.isNotEmpty()) {
|
||||
return toggleSelection(position)
|
||||
return if (allowSelection) {
|
||||
super.onItemClick(position)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun onItemLongClick(position: Int): Boolean {
|
||||
override fun onItemLongClick(position: Int): Boolean {
|
||||
onVolumeItemLongClick()
|
||||
return if (allowSelection)
|
||||
toggleSelection(position)
|
||||
super.onItemLongClick(position)
|
||||
else
|
||||
false
|
||||
}
|
||||
@ -67,27 +61,6 @@ class VolumeAdapter(
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
|
||||
fun selectAll() {
|
||||
for (i in volumes.indices) {
|
||||
if (!selectedItems.contains(i)) {
|
||||
selectedItems.add(i)
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun unSelectAll(notifyChange: Boolean) {
|
||||
if (notifyChange) {
|
||||
val whatWasSelected = selectedItems
|
||||
selectedItems = HashSet()
|
||||
whatWasSelected.forEach {
|
||||
notifyItemChanged(it)
|
||||
}
|
||||
} else {
|
||||
selectedItems.clear()
|
||||
}
|
||||
}
|
||||
|
||||
fun refresh() {
|
||||
reloadVolumes()
|
||||
unSelectAll(true)
|
||||
@ -95,10 +68,6 @@ class VolumeAdapter(
|
||||
|
||||
inner class VolumeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
private fun setBackground(isSelected: Boolean) {
|
||||
itemView.setBackgroundResource(if (isSelected) R.color.itemSelected else 0)
|
||||
}
|
||||
|
||||
fun bind(position: Int) {
|
||||
val volume = volumes[position]
|
||||
itemView.findViewById<TextView>(R.id.text_volume_name).text = volume.shortName
|
||||
@ -123,18 +92,7 @@ class VolumeAdapter(
|
||||
visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
(bindingAdapter as VolumeAdapter?)?.let { adapter ->
|
||||
itemView.findViewById<LinearLayout>(R.id.selectable_container).apply {
|
||||
setOnClickListener {
|
||||
setBackground(adapter.onItemClick(layoutPosition))
|
||||
}
|
||||
setOnLongClickListener {
|
||||
setBackground(adapter.onItemLongClick(layoutPosition))
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
setBackground(selectedItems.contains(position))
|
||||
setSelectable(itemView.findViewById<LinearLayout>(R.id.selectable_container), itemView, layoutPosition)
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,8 +104,4 @@ class VolumeAdapter(
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
(holder as VolumeViewHolder).bind(position)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return volumes.size
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user