diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/AnimatedItemsAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/AnimatedItemsAdapter.kt new file mode 100644 index 000000000..b9b9b2345 --- /dev/null +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/AnimatedItemsAdapter.kt @@ -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(val context: Context) + : RecyclerView.Adapter() { + + protected val inflater: LayoutInflater = LayoutInflater.from(context) + var itemsList: MutableList = 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) { + 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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/EntryAttachmentsAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/EntryAttachmentsItemsAdapter.kt similarity index 62% rename from app/src/main/java/com/kunzisoft/keepass/adapters/EntryAttachmentsAdapter.kt rename to app/src/main/java/com/kunzisoft/keepass/adapters/EntryAttachmentsItemsAdapter.kt index a1873651b..9781fff05 100644 --- a/app/src/main/java/com/kunzisoft/keepass/adapters/EntryAttachmentsAdapter.kt +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/EntryAttachmentsItemsAdapter.kt @@ -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() { +class EntryAttachmentsItemsAdapter(context: Context, private val editable: Boolean) + : AnimatedItemsAdapter(context) { - private val inflater: LayoutInflater = LayoutInflater.from(context) - var entryAttachmentsList: MutableList = 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) { - 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) diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/EntryExtraFieldsAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/EntryExtraFieldsItemsAdapter.kt similarity index 64% rename from app/src/main/java/com/kunzisoft/keepass/adapters/EntryExtraFieldsAdapter.kt rename to app/src/main/java/com/kunzisoft/keepass/adapters/EntryExtraFieldsItemsAdapter.kt index ca924e4d4..d34c340ae 100644 --- a/app/src/main/java/com/kunzisoft/keepass/adapters/EntryExtraFieldsAdapter.kt +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/EntryExtraFieldsItemsAdapter.kt @@ -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() { - - private val inflater: LayoutInflater = LayoutInflater.from(context) - var extraFieldsList: MutableList = ArrayList() - private set - var onDeleteButtonClickListener: ((item: Field)->Unit)? = null - var onListSizeChangedListener: ((previousSize: Int, newSize: Int)->Unit)? = null +class EntryExtraFieldsItemsAdapter(context: Context) + : AnimatedItemsAdapter(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) { - 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) { diff --git a/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt b/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt index 475c96434..940979d90 100644 --- a/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt +++ b/app/src/main/java/com/kunzisoft/keepass/view/EntryContentsView.kt @@ -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, onAttachmentClicked: (attachment: EntryAttachment)->Unit) { showAttachments(attachments.isNotEmpty()) - attachmentsAdapter.assignAttachments(attachments) + attachmentsAdapter.assignItems(attachments) attachmentsAdapter.onItemClickListener = { item -> onAttachmentClicked.invoke(item) } diff --git a/app/src/main/java/com/kunzisoft/keepass/view/EntryEditContentsView.kt b/app/src/main/java/com/kunzisoft/keepass/view/EntryEditContentsView.kt index 74d773bac..26673067a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/view/EntryEditContentsView.kt +++ b/app/src/main/java/com/kunzisoft/keepass/view/EntryEditContentsView.kt @@ -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 { - return extraFieldsAdapter.extraFieldsList + return extraFieldsAdapter.itemsList } /** @@ -250,7 +250,7 @@ class EntryEditContentsView @JvmOverloads constructor(context: Context, */ fun assignExtraFields(fields: List) { 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, 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) }