Skip to content

Instantly share code, notes, and snippets.

@Bloody-Badboy
Created October 13, 2020 05:21
Show Gist options
  • Save Bloody-Badboy/60792fd4b5e9eb29a5bc7bda1f993029 to your computer and use it in GitHub Desktop.
Save Bloody-Badboy/60792fd4b5e9eb29a5bc7bda1f993029 to your computer and use it in GitHub Desktop.
RecycleView Single Choice & Multiple Choice Adapter
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:checkMark="?android:attr/listChoiceIndicatorSingle"
android:gravity="center_vertical"
android:background="?attr/selectableItemBackground"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:textAppearance="?android:attr/textAppearanceListItemSmall" />
package dev.arpan
import android.util.SparseBooleanArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckedTextView
import androidx.recyclerview.widget.RecyclerView
import dev.arpan.ecommerce.R
typealias OnSelectionChange = (positions: List<Int>) -> Unit
class MultipleChoiceListAdapter(private val listener: OnSelectionChange) :
RecyclerView.Adapter<MultipleChoiceListAdapter.MultipleChoiceItemViewHolder>() {
private val selections = SparseBooleanArray()
private val selectedPositions: List<Int>
get() {
return mutableListOf<Int>().apply {
for (i in 0 until selections.size()) {
if (selections.valueAt(i)) {
add(selections.keyAt(i))
}
}
}
}
var data: List<String> = emptyList()
set(value) {
field = value
notifyDataSetChanged()
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): MultipleChoiceItemViewHolder {
return MultipleChoiceItemViewHolder.create(parent)
}
override fun onBindViewHolder(holder: MultipleChoiceItemViewHolder, position: Int) {
(holder.itemView as? CheckedTextView)?.apply {
text = data[position]
isChecked = selections.get(position)
setOnClickListener {
selections.put(position, !isChecked)
notifyItemChanged(position)
listener.invoke(selectedPositions)
}
}
}
override fun getItemCount() = data.size
class MultipleChoiceItemViewHolder private constructor(private val view: View) :
RecyclerView.ViewHolder(view) {
companion object {
fun create(parent: ViewGroup): MultipleChoiceItemViewHolder {
return MultipleChoiceItemViewHolder(
view = LayoutInflater.from(parent.context)
.inflate(
R.layout.item_simple_list_checkable,
parent, false
)
)
}
}
}
package dev.arpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckedTextView
import android.widget.TextView
import androidx.annotation.LayoutRes
import androidx.recyclerview.widget.RecyclerView
import dev.arpan.ecommerce.R
import kotlin.properties.Delegates
typealias OnSelectItemListener = (position: Int) -> Unit
class SingleChoiceListAdapter(
private val checkable: Boolean = true,
private val itemListener: OnSelectItemListener? = null
) :
RecyclerView.Adapter<SingleChoiceListAdapter.SingleChoiceItemViewHolder>() {
var data: List<String> = emptyList()
set(value) {
field = value
notifyDataSetChanged()
}
var selectedPosition by Delegates.observable(-1) { _, oldPos, newPos ->
if (newPos in data.indices) {
notifyItemChanged(oldPos)
notifyItemChanged(newPos)
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SingleChoiceItemViewHolder {
return SingleChoiceItemViewHolder.create(
if (checkable) R.layout.item_simple_list_checkable else R.layout.item_simple_list,
parent
)
}
override fun onBindViewHolder(holder: SingleChoiceItemViewHolder, position: Int) {
holder.bind(data[position], position == selectedPosition)
holder.itemView.setOnClickListener {
selectedPosition = position
itemListener?.invoke(position)
}
}
override fun getItemCount() = data.size
class SingleChoiceItemViewHolder(private val view: View) :
RecyclerView.ViewHolder(view) {
fun bind(s: String, selected: Boolean) {
(view as? TextView)?.apply {
text = s
isSelected = selected
}
(view as? CheckedTextView)?.apply {
isChecked = selected
}
}
companion object {
fun create(@LayoutRes layout: Int, parent: ViewGroup): SingleChoiceItemViewHolder {
return SingleChoiceItemViewHolder(
view = LayoutInflater.from(parent.context).inflate(layout, parent, false)
)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment