Last active
March 28, 2023 08:25
-
-
Save nikhil-thakkar/74a08d694b8ac1c68a5d176dbb92eb4e to your computer and use it in GitHub Desktop.
Generic databinding adapter for items in Recyclerview
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<layout> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<androidx.recyclerview.widget.RecyclerView | |
android:id="@+id/rv" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"/> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</layout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<layout> | |
<data> | |
<variable name="model" type="String"/> | |
</data> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:paddingStart="@dimen/margin_padding_32" | |
android:paddingEnd="@dimen/margin_padding_0" | |
android:background="@color/pale_grey" | |
android:paddingTop="@dimen/margin_padding_12" | |
android:paddingBottom="@dimen/margin_padding_12"> | |
<TextView android:id="@+id/content" | |
android:layout_width="match_parent" | |
tools:text="The Basics" | |
android:textAllCaps="true" | |
android:layout_height="wrap_content" | |
android:text="@{model}"/> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</layout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<layout> | |
<data> | |
<variable name="model" type="String"/> | |
</data> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:paddingStart="@dimen/margin_padding_32" | |
android:paddingEnd="@dimen/margin_padding_0" | |
android:background="@color/pale_grey" | |
android:paddingTop="@dimen/margin_padding_12" | |
android:paddingBottom="@dimen/margin_padding_12"> | |
<TextView android:id="@+id/desc" | |
android:layout_width="match_parent" | |
tools:text="The Basics" | |
android:textAllCaps="true" | |
android:layout_height="wrap_content" | |
android:text="@{model}"/> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</layout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data class HeaderViewType(private val title: String?= null) : ViewType<String?> { | |
override fun layoutId(): Int = R.layout.item_header | |
override fun data(): String? = title | |
override fun isUserInteractionEnabled() = false | |
} | |
data class RowViewType(private val content: String?= null) : ViewType<String?> { | |
override fun layoutId(): Int = R.layout.item_header | |
override fun data(): String? = content | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.recyclerview.widget.RecyclerView | |
class SampleActivity: Activity(), OnItemActionListener { | |
private val adapter by lazy { ViewTypeAdapter<ViewType<*>>(list = list, onItemActionListener = this) } | |
//Prepare the list somehow, whether in ViewModel or presenter and then set it to adapter using setList | |
private val list: List<ViewType<*>> by lazy { | |
arrayListOf<>(HeaderViewType("Header"), | |
RowViewType("content"), | |
RowViewType("content"), | |
RowViewType("content")) | |
} | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_main) | |
val rv = findViewById(R.id.rv) | |
rv.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false) | |
rv.adapter = adapter | |
} | |
override fun onItemClicked(position: Int) { | |
//Do whatever you want to do with position | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.annotation.LayoutRes | |
/** | |
* Different view types for [RecyclerView] | |
*/ | |
interface ViewType<out T> { | |
@LayoutRes | |
fun layoutId(): Int | |
fun data(): T | |
fun isUserInteractionEnabled() = true | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.view.LayoutInflater | |
import android.view.ViewGroup | |
import androidx.databinding.DataBindingUtil | |
import androidx.databinding.ViewDataBinding | |
import androidx.recyclerview.widget.RecyclerView | |
import *.BR | |
/** | |
* Adapter to populate the list of list | |
*/ | |
class ViewTypeAdapter<E : ViewType<*>>( | |
private var list: MutableList<E> = mutableListOf(), | |
private val onItemActionListener: OnItemActionListener? = null | |
) : RecyclerView.Adapter<ViewTypeHolder>() { | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewTypeHolder { | |
val binding: ViewDataBinding = | |
DataBindingUtil.inflate(LayoutInflater.from(parent.context), viewType, parent, false) | |
return ViewTypeHolder(binding, onItemActionListener) | |
} | |
override fun onBindViewHolder(holder: ViewTypeHolder, position: Int) { | |
holder.bindItem(list[position]) | |
} | |
override fun getItemViewType(position: Int): Int = list[position].layoutId() | |
override fun getItemCount(): Int = list.size | |
override fun setList(list: List<E>) { | |
this.list.clear() | |
this.list.addAll(list) | |
notifyDataSetChanged() | |
} | |
fun insertElement(data: E, position: Int? = null) { | |
if (position != null) { | |
this.list.add(position, data) | |
notifyItemInserted(position) | |
} else { | |
this.list.add(data) | |
notifyItemInserted(this.list.size - 1) | |
} | |
} | |
fun updateElement(data: E, position: Int) { | |
this.list[position] = data | |
notifyItemChanged(position) | |
} | |
} | |
class ViewTypeHolder(private val binding: ViewDataBinding, private val onItemActionListener: OnItemActionListener?) : | |
RecyclerView.ViewHolder(binding.root) { | |
fun bindItem(item: ViewType<*>) { | |
binding.setVariable(BR.model, item.data()) | |
if (item.isUserInteractionEnabled()) { | |
binding.setVariable(BR.position, adapterPosition) | |
binding.setVariable(BR.actionItemListener, onItemActionListener) | |
} | |
binding.executePendingBindings() | |
} | |
} | |
interface OnItemActionListener { | |
fun onItemClicked(position: Int) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment