Skip to content

Instantly share code, notes, and snippets.

@Miha-x64
Last active July 10, 2023 09:24
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Miha-x64/3248e4b08ec31094ed65e00565aa8ff3 to your computer and use it in GitHub Desktop.
Save Miha-x64/3248e4b08ec31094ed65e00565aa8ff3 to your computer and use it in GitHub Desktop.
Another approach to EditTexts inside RecyclerView
import android.text.Editable
import android.text.SpannableStringBuilder
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.EditText
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
/**
* Another approach to EditTexts inside RecyclerView.
* @author Mike Gorünóv
*/
class EditableAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val editables = ArrayList<Editable?>()
private var strings = emptyList<String>()
@Suppress("SetterBackingFieldAssignment")
var items: List<String> =
object : AbstractList<String>() {
override val size: Int get() = strings.size
override fun get(index: Int): String = editables.getOrNull(index)?.toString() ?: strings[index]
}
set(value) {
DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun getOldListSize(): Int = strings.size
override fun getNewListSize(): Int = value.size
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
(editables.getOrNull(oldItemPosition) ?: strings[oldItemPosition])
.contentEquals(value[newItemPosition])
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
areItemsTheSame(oldItemPosition, newItemPosition)
}).dispatchUpdatesTo(this)
editables.clear()
strings = value
notifyItemRangeChanged(0, strings.size, Unit) // drop and recreate editables for bound views
}
override fun getItemCount(): Int =
strings.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
object : RecyclerView.ViewHolder(EditText(parent.context).apply {
layoutParams = RecyclerView.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
setEditableFactory(IdentityEditableFactory)
}) {}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
(holder.itemView as EditText).text = editables.getOrNull(position)
?: SpannableStringBuilder(strings[position]).also {
while (editables.lastIndex < position) editables.add(null)
editables[position] = it
}
}
private object IdentityEditableFactory : Editable.Factory() {
override fun newEditable(source: CharSequence): Editable = source as Editable
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment