mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Encapsulate adapters in AnimatedItemsAdapter
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
package com.kunzisoft.keepass.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.kunzisoft.keepass.view.collapse
|
||||
|
||||
abstract class AnimatedItemsAdapter<Item, T: RecyclerView.ViewHolder>(val context: Context)
|
||||
: RecyclerView.Adapter<T>() {
|
||||
|
||||
protected val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
var itemsList: MutableList<Item> = ArrayList()
|
||||
private set
|
||||
|
||||
var onDeleteButtonClickListener: ((item: Item)->Unit)? = null
|
||||
private var mItemToRemove: Item? = null
|
||||
|
||||
var onListSizeChangedListener: ((previousSize: Int, newSize: Int)->Unit)? = null
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return itemsList.size
|
||||
}
|
||||
|
||||
fun assignItems(items: List<Item>) {
|
||||
val previousSize = itemsList.size
|
||||
itemsList.apply {
|
||||
clear()
|
||||
addAll(items)
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
onListSizeChangedListener?.invoke(previousSize, itemsList.size)
|
||||
}
|
||||
|
||||
fun onBindDeleteButton(holder: T, deleteButton: View, item: Item, position: Int) {
|
||||
deleteButton.apply {
|
||||
visibility = View.VISIBLE
|
||||
if (mItemToRemove == item) {
|
||||
holder.itemView.collapse(true) {
|
||||
deleteItem(item)
|
||||
}
|
||||
setOnClickListener(null)
|
||||
} else {
|
||||
setOnClickListener {
|
||||
onDeleteButtonClickListener?.invoke(item)
|
||||
mItemToRemove = item
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteItem(item: Item) {
|
||||
val previousSize = itemsList.size
|
||||
val position = itemsList.indexOf(item)
|
||||
if (position >= 0) {
|
||||
itemsList.removeAt(position)
|
||||
notifyItemRemoved(position)
|
||||
mItemToRemove = null
|
||||
for (i in 0 until itemsList.size) {
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
}
|
||||
onListSizeChangedListener?.invoke(previousSize, itemsList.size)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
itemsList.clear()
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ package com.kunzisoft.keepass.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.text.format.Formatter
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ProgressBar
|
||||
@@ -32,18 +31,11 @@ import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
||||
import com.kunzisoft.keepass.model.AttachmentState
|
||||
import com.kunzisoft.keepass.model.EntryAttachment
|
||||
import com.kunzisoft.keepass.view.collapse
|
||||
|
||||
class EntryAttachmentsAdapter(val context: Context, private val editable: Boolean)
|
||||
: RecyclerView.Adapter<EntryAttachmentsAdapter.EntryBinariesViewHolder>() {
|
||||
class EntryAttachmentsItemsAdapter(context: Context, private val editable: Boolean)
|
||||
: AnimatedItemsAdapter<EntryAttachment, EntryAttachmentsItemsAdapter.EntryBinariesViewHolder>(context) {
|
||||
|
||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
var entryAttachmentsList: MutableList<EntryAttachment> = ArrayList()
|
||||
var onItemClickListener: ((item: EntryAttachment)->Unit)? = null
|
||||
var onDeleteButtonClickListener: ((item: EntryAttachment)->Unit)? = null
|
||||
var onListSizeChangedListener: ((previousSize: Int, newSize: Int)->Unit)? = null
|
||||
|
||||
private var mAttachmentToRemove: EntryAttachment? = null
|
||||
|
||||
private val mDatabase = Database.getInstance()
|
||||
|
||||
@@ -52,7 +44,7 @@ class EntryAttachmentsAdapter(val context: Context, private val editable: Boolea
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: EntryBinariesViewHolder, position: Int) {
|
||||
val entryAttachment = entryAttachmentsList[position]
|
||||
val entryAttachment = itemsList[position]
|
||||
|
||||
holder.itemView.visibility = View.VISIBLE
|
||||
holder.binaryFileTitle.text = entryAttachment.name
|
||||
@@ -72,18 +64,7 @@ class EntryAttachmentsAdapter(val context: Context, private val editable: Boolea
|
||||
holder.binaryFileProgressContainer.visibility = View.GONE
|
||||
holder.binaryFileDeleteButton.apply {
|
||||
visibility = View.VISIBLE
|
||||
if (mAttachmentToRemove == entryAttachment) {
|
||||
holder.itemView.collapse(true) {
|
||||
deleteAttachment(entryAttachment)
|
||||
}
|
||||
setOnClickListener(null)
|
||||
} else {
|
||||
setOnClickListener {
|
||||
onDeleteButtonClickListener?.invoke(entryAttachment)
|
||||
mAttachmentToRemove = entryAttachment
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
onBindDeleteButton(holder, this, entryAttachment, position)
|
||||
}
|
||||
} else {
|
||||
holder.binaryFileProgressContainer.visibility = View.VISIBLE
|
||||
@@ -101,46 +82,14 @@ class EntryAttachmentsAdapter(val context: Context, private val editable: Boolea
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return entryAttachmentsList.size
|
||||
}
|
||||
|
||||
fun assignAttachments(attachments: List<EntryAttachment>) {
|
||||
val previousSize = entryAttachmentsList.size
|
||||
entryAttachmentsList.apply {
|
||||
clear()
|
||||
addAll(attachments)
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
onListSizeChangedListener?.invoke(previousSize, entryAttachmentsList.size)
|
||||
}
|
||||
|
||||
private fun deleteAttachment(attachment: EntryAttachment) {
|
||||
val previousSize = entryAttachmentsList.size
|
||||
val position = entryAttachmentsList.indexOf(attachment)
|
||||
if (position >= 0) {
|
||||
entryAttachmentsList.removeAt(position)
|
||||
notifyItemRemoved(position)
|
||||
mAttachmentToRemove = null
|
||||
for (i in 0 until entryAttachmentsList.size) {
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
}
|
||||
onListSizeChangedListener?.invoke(previousSize, entryAttachmentsList.size)
|
||||
}
|
||||
|
||||
fun updateProgress(entryAttachment: EntryAttachment) {
|
||||
val indexEntryAttachment = entryAttachmentsList.indexOfLast { current -> current.name == entryAttachment.name }
|
||||
val indexEntryAttachment = itemsList.indexOfLast { current -> current.name == entryAttachment.name }
|
||||
if (indexEntryAttachment != -1) {
|
||||
entryAttachmentsList[indexEntryAttachment] = entryAttachment
|
||||
itemsList[indexEntryAttachment] = entryAttachment
|
||||
notifyItemChanged(indexEntryAttachment)
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
entryAttachmentsList.clear()
|
||||
}
|
||||
|
||||
inner class EntryBinariesViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
var binaryFileTitle: TextView = itemView.findViewById(R.id.item_attachment_title)
|
||||
@@ -20,7 +20,6 @@
|
||||
package com.kunzisoft.keepass.adapters
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
@@ -32,16 +31,9 @@ import com.google.android.material.textfield.TextInputLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.model.Field
|
||||
import com.kunzisoft.keepass.view.applyFontVisibility
|
||||
import com.kunzisoft.keepass.view.collapse
|
||||
|
||||
class EntryExtraFieldsAdapter(val context: Context)
|
||||
: RecyclerView.Adapter<EntryExtraFieldsAdapter.EntryExtraFieldViewHolder>() {
|
||||
|
||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
||||
var extraFieldsList: MutableList<Field> = ArrayList()
|
||||
private set
|
||||
var onDeleteButtonClickListener: ((item: Field)->Unit)? = null
|
||||
var onListSizeChangedListener: ((previousSize: Int, newSize: Int)->Unit)? = null
|
||||
class EntryExtraFieldsItemsAdapter(context: Context)
|
||||
: AnimatedItemsAdapter<Field, EntryExtraFieldsItemsAdapter.EntryExtraFieldViewHolder>(context) {
|
||||
|
||||
var applyFontVisibility = false
|
||||
set(value) {
|
||||
@@ -49,7 +41,6 @@ class EntryExtraFieldsAdapter(val context: Context)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
private var mValueViewInputType: Int = 0
|
||||
private var mItemToRemove: Field? = null
|
||||
private var mLastFocused: Field? = null
|
||||
private var mLastFocusedTimestamp: Long = 0
|
||||
|
||||
@@ -62,7 +53,7 @@ class EntryExtraFieldsAdapter(val context: Context)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: EntryExtraFieldViewHolder, position: Int) {
|
||||
val extraField = extraFieldsList[position]
|
||||
val extraField = itemsList[position]
|
||||
|
||||
holder.itemView.visibility = View.VISIBLE
|
||||
if (extraField.protectedValue.isProtected) {
|
||||
@@ -94,18 +85,7 @@ class EntryExtraFieldsAdapter(val context: Context)
|
||||
applyFontVisibility()
|
||||
}
|
||||
holder.extraFieldDeleteButton.apply {
|
||||
if (mItemToRemove == extraField) {
|
||||
holder.itemView.collapse(true) {
|
||||
deleteExtraField(extraField)
|
||||
}
|
||||
setOnClickListener(null)
|
||||
} else {
|
||||
setOnClickListener {
|
||||
onDeleteButtonClickListener?.invoke(extraField)
|
||||
mItemToRemove = extraField
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
onBindDeleteButton(holder, this, extraField, position)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,52 +110,20 @@ class EntryExtraFieldsAdapter(val context: Context)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return extraFieldsList.size
|
||||
}
|
||||
|
||||
fun assignExtraFields(fields: List<Field>) {
|
||||
val previousSize = extraFieldsList.size
|
||||
extraFieldsList.apply {
|
||||
clear()
|
||||
addAll(fields)
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
onListSizeChangedListener?.invoke(previousSize, extraFieldsList.size)
|
||||
}
|
||||
|
||||
fun putExtraField(field: Field) {
|
||||
val previousSize = extraFieldsList.size
|
||||
if (extraFieldsList.contains(field)) {
|
||||
val index = extraFieldsList.indexOf(field)
|
||||
extraFieldsList.removeAt(index)
|
||||
extraFieldsList.add(index, field)
|
||||
val previousSize = itemsList.size
|
||||
if (itemsList.contains(field)) {
|
||||
val index = itemsList.indexOf(field)
|
||||
itemsList.removeAt(index)
|
||||
itemsList.add(index, field)
|
||||
focusField(field)
|
||||
notifyItemChanged(index)
|
||||
} else {
|
||||
extraFieldsList.add(field)
|
||||
itemsList.add(field)
|
||||
focusField(field)
|
||||
notifyItemInserted(extraFieldsList.indexOf(field))
|
||||
notifyItemInserted(itemsList.indexOf(field))
|
||||
}
|
||||
onListSizeChangedListener?.invoke(previousSize, extraFieldsList.size)
|
||||
}
|
||||
|
||||
private fun deleteExtraField(field: Field) {
|
||||
val previousSize = extraFieldsList.size
|
||||
val position = extraFieldsList.indexOf(field)
|
||||
if (position >= 0) {
|
||||
extraFieldsList.removeAt(position)
|
||||
notifyItemRemoved(position)
|
||||
mItemToRemove = null
|
||||
for (i in 0 until extraFieldsList.size) {
|
||||
notifyItemChanged(i)
|
||||
}
|
||||
}
|
||||
onListSizeChangedListener?.invoke(previousSize, extraFieldsList.size)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
extraFieldsList.clear()
|
||||
onListSizeChangedListener?.invoke(previousSize, itemsList.size)
|
||||
}
|
||||
|
||||
inner class EntryExtraFieldViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
@@ -33,7 +33,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.adapters.EntryAttachmentsAdapter
|
||||
import com.kunzisoft.keepass.adapters.EntryAttachmentsItemsAdapter
|
||||
import com.kunzisoft.keepass.adapters.EntryHistoryAdapter
|
||||
import com.kunzisoft.keepass.database.element.DateInstant
|
||||
import com.kunzisoft.keepass.database.element.Entry
|
||||
@@ -84,7 +84,7 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
||||
|
||||
private val attachmentsContainerView: View
|
||||
private val attachmentsListView: RecyclerView
|
||||
private val attachmentsAdapter = EntryAttachmentsAdapter(context, false)
|
||||
private val attachmentsAdapter = EntryAttachmentsItemsAdapter(context, false)
|
||||
|
||||
private val historyContainerView: View
|
||||
private val historyListView: RecyclerView
|
||||
@@ -367,7 +367,7 @@ class EntryContentsView @JvmOverloads constructor(context: Context,
|
||||
fun assignAttachments(attachments: ArrayList<EntryAttachment>,
|
||||
onAttachmentClicked: (attachment: EntryAttachment)->Unit) {
|
||||
showAttachments(attachments.isNotEmpty())
|
||||
attachmentsAdapter.assignAttachments(attachments)
|
||||
attachmentsAdapter.assignItems(attachments)
|
||||
attachmentsAdapter.onItemClickListener = { item ->
|
||||
onAttachmentClicked.invoke(item)
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.adapters.EntryAttachmentsAdapter
|
||||
import com.kunzisoft.keepass.adapters.EntryExtraFieldsAdapter
|
||||
import com.kunzisoft.keepass.adapters.EntryAttachmentsItemsAdapter
|
||||
import com.kunzisoft.keepass.adapters.EntryExtraFieldsItemsAdapter
|
||||
import com.kunzisoft.keepass.database.element.DateInstant
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImage
|
||||
import com.kunzisoft.keepass.icons.IconDrawableFactory
|
||||
@@ -66,8 +66,8 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
private val attachmentsContainerView: View
|
||||
private val attachmentsListView: RecyclerView
|
||||
|
||||
private val extraFieldsAdapter = EntryExtraFieldsAdapter(context)
|
||||
private val attachmentsAdapter = EntryAttachmentsAdapter(context, true)
|
||||
private val extraFieldsAdapter = EntryExtraFieldsItemsAdapter(context)
|
||||
private val attachmentsAdapter = EntryAttachmentsItemsAdapter(context, true)
|
||||
|
||||
private var iconColor: Int = 0
|
||||
private var expiresInstant: DateInstant = DateInstant(Instant.now().plus(Duration.standardDays(30)).toDate())
|
||||
@@ -242,7 +242,7 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
*/
|
||||
|
||||
fun getExtraField(): MutableList<Field> {
|
||||
return extraFieldsAdapter.extraFieldsList
|
||||
return extraFieldsAdapter.itemsList
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,7 +250,7 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
*/
|
||||
fun assignExtraFields(fields: List<Field>) {
|
||||
extraFieldsContainerView.visibility = if (fields.isEmpty()) View.GONE else View.VISIBLE
|
||||
extraFieldsAdapter.assignExtraFields(fields)
|
||||
extraFieldsAdapter.assignItems(fields)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,7 +270,7 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context,
|
||||
fun assignAttachments(attachments: ArrayList<EntryAttachment>,
|
||||
onDeleteItem: (attachment: EntryAttachment)->Unit) {
|
||||
attachmentsContainerView.visibility = if (attachments.isEmpty()) View.GONE else View.VISIBLE
|
||||
attachmentsAdapter.assignAttachments(attachments)
|
||||
attachmentsAdapter.assignItems(attachments)
|
||||
attachmentsAdapter.onDeleteButtonClickListener = { item ->
|
||||
onDeleteItem.invoke(item)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user