Reputation: 227
I know that RecyclerView lists are flexible and that it's possible to have multiple views in each item. I can't find any good example code that will help me implement this.
I am trying to implement a simple RecyclerView list with each list item as a custom .xml layout that I have created. What must be done in for the RecyclerView.Adapter to be able to access each different view by its ID from the custom layout file and be able to update each value?
I've basically copied the following code from Android Docs.
//ScannedDevicesListAdapter.kt
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class ScannedDevicesListAdapter(private val myDataset: Array<String>) :
RecyclerView.Adapter<ScannedDevicesListAdapter.ScannedDevicesListViewHolder>() {
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder.
// Each data item is just a string in this case that is shown in a TextView.
class ScannedDevicesListViewHolder(val textView: TextView) : RecyclerView.ViewHolder(textView)
// Create new views (invoked by the layout manager)
override fun onCreateViewHolder(parent: ViewGroup,
viewType: Int): ScannedDevicesListAdapter.ScannedDevicesListViewHolder {
// create a new view
val textView = LayoutInflater.from(parent.context)
.inflate(R.layout.scanned_devices_list_item, parent, false) as TextView
// set the view's size, margins, paddings and layout parameters
return ScannedDevicesListViewHolder(textView)
}
// Replace the contents of a view (invoked by the layout manager)
override fun onBindViewHolder(holder: ScannedDevicesListViewHolder, position: Int) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.textView.text = myDataset[position]
}
// Return the size of your dataset (invoked by the layout manager)
override fun getItemCount() = myDataset.size
}
Here is the .xml file for my custom view:
Screenshot of the custom list item
//scanned_devices_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:padding="30dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/TextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:text="Field 1" />
<TextView
android:id="@+id/TextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:text="Field 2" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="@+id/TextView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:text="Field 3" />
</LinearLayout>
</LinearLayout>
Upvotes: 1
Views: 1752
Reputation: 1
You Can try this....
class sel_cat_adapter(ctx: Context, list: MutableList<Any>) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private var ctx: Context = ctx
private var list: MutableList<Any> = list
private var ITEM = 0
private var Ads = 1
var ITEM_PER_Ad = 5
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
ITEM -> {
var inflater =
LayoutInflater.from(ctx).inflate(R.layout.customlayoutfor_sel_cat, null, false)
return viewholderclass(inflater)
}
Ads -> {
var inflater = LayoutInflater.from(ctx).inflate(R.layout.ads_banner, null, false)
return AdsViewHolder(inflater)
}
else -> {
var inflater = LayoutInflater.from(ctx).inflate(R.layout.ads_banner, null, false)
return AdsViewHolder(inflater)
}
}
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
var viewtype = getItemViewType(position)
when (viewtype) {
ITEM -> {
var myholder = holder as viewholderclass
}
Ads -> {
var myholder = holder as AdsViewHolder
}
else -> {
}
}
holder.itemView.setOnClickListener {
if (viewtype == ITEM) {
Toast.makeText(ctx, "Item", Toast.LENGTH_LONG).show()
} else {
Toast.makeText(ctx, "Ads", Toast.LENGTH_LONG).show()
}
}
}
override fun getItemViewType(position: Int): Int {
return if (position % ITEM_PER_Ad == 0) {
if (list[position] is AdView) {
Ads
} else {
ITEM
}
} else {
ITEM
}
}
class AdsViewHolder(itemview: View) : RecyclerView.ViewHolder(itemview){
}
class viewholderclass(itemview: View) : RecyclerView.ViewHolder(itemview) {
}
}
Upvotes: 0
Reputation: 14660
You should change your ViewHolder
implementation as it should take your parent View
(from the xml file) as a parameter not a TextView
. TextView
s are subitems that can be defined as member variables in your ViewHolder
:
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class ScannedDevicesListAdapter(private val myDataset: Array<String>) :
RecyclerView.Adapter<ScannedDevicesListAdapter.ScannedDevicesListViewHolder>() {
class ScannedDevicesListViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
val tv1 = view.TextView1
val tv2 = view.TextView2
val tv3 = view.TextView3
}
// Create new views (invoked by the layout manager)
override fun onCreateViewHolder(parent: ViewGroup,
viewType: Int):
ScannedDevicesListAdapter.ScannedDevicesListViewHolder {
// create a new view
val linearLayout = LayoutInflater.from(parent.context)
.inflate(R.layout.scanned_devices_list_item, parent, false) as View
// set the view's size, margins, paddings and layout parameters
return ScannedDevicesListViewHolder(linearLayout)
}
override fun onBindViewHolder(holder: ScannedDevicesListViewHolder, position: Int) {
holder.tv1.text = myDataset[position]
// set your other views here
}
// Return the size of your dataset (invoked by the layout manager)
override fun getItemCount() = myDataset.size
}
Upvotes: 1