I am developing an Android application in Kotlin and I implemented a RecyclerView.
Each item of this RecyclerView contains one of the 3 combinations below:
- a TextView + a TextView
- a TextView + a Button
- a TextView + a Spinner
My problem is simply that nothing is displayed! I don't understand my mistake, can you help me?
Here is my adapter:
class CustomAdapter(private val dataSet: Array<Parameter>) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class TextViewHolder(itemView: View) : ViewHolder(itemView) {
val textViewName: TextView = itemView.findViewById(R.id.parameterName)
val textViewValue: TextView = itemView.findViewById(R.id.parameterValue)
}
class ButtonViewHolder(itemView: View) : ViewHolder(itemView) {
var textViewName: TextView = itemView.findViewById(R.id.parameterName)
val buttonViewValue: Button = itemView.findViewById(R.id.parameterButton)
}
class SpinnerViewHolder(itemView: View) : ViewHolder(itemView) {
val textViewName: TextView = itemView.findViewById(R.id.parameterName)
val spinnerViewValue: Spinner = itemView.findViewById(R.id.parameterSpinner)
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
return when (viewType) {
0 -> {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.parameter_text, viewGroup, false)
ViewHolder.TextViewHolder(view)
}
1 -> {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.parameter_button, viewGroup, false)
ViewHolder.ButtonViewHolder(view)
}
2 -> {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.parameter_spinner, viewGroup, false)
ViewHolder.SpinnerViewHolder(view)
}
else -> throw IllegalArgumentException("Invalid view type")
}
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
when (viewHolder) {
is ViewHolder.TextViewHolder -> {
viewHolder.textViewName.text = dataSet[position].parameterName
viewHolder.textViewValue.text = dataSet[position].parameterValue as CharSequence?
}
is ViewHolder.ButtonViewHolder -> {
viewHolder.textViewName.text = dataSet[position].parameterName
viewHolder.buttonViewValue.text = dataSet[position].parameterValue as CharSequence?
}
is ViewHolder.SpinnerViewHolder -> {
viewHolder.textViewName.text = dataSet[position].parameterName
viewHolder.spinnerViewValue.adapter = dataSet[position].parameterValue as SpinnerAdapter?
}
}
}
override fun getItemViewType(position: Int) : Int {
return dataSet[position].parameterType
}
override fun getItemCount() = dataSet.size
}
Each of the different types of parameters inherited from the class Parameter:
open class Parameter(open var parameterName: String? = "", open var parameterType: Int = 0, open var parameterValue: Any) {
}
ParameterText class:
class ParameterText(override var parameterName: String?, override var parameterValue: Any = "") : Parameter(parameterName, parameterValue = parameterValue!!) {
override var parameterType: Int = 0
}
ParameterButton class:
class ParameterButton(override var parameterName: String?, override var parameterValue: Any = "") : Parameter(parameterName, parameterValue = parameterValue!!) {
override var parameterType: Int = 1
}
ParameterSpinner class:
class ParameterSpinner(override var parameterName: String?, override var parameterValue: Any) : Parameter(parameterName, parameterValue = parameterValue) {
override var parameterType: Int = 2
}
In the OnCreate method, I initialize the RecyclerView:
rv_parameters.layoutManager = LinearLayoutManager(this)
rv_parameters.adapter = CustomAdapter(parametersList)
Here is my list of parameters:
private val parametersList = emptyArray<Parameter>()
And finally, here is how I add parameters to this list:
append(parametersList, ParameterText("Temperature", "24°C"))
Using this method:
fun append(arr: Array<Parameter>, element: Parameter): Array<Parameter?> {
val array = arrayOfNulls<Parameter>(arr.size + 1)
System.arraycopy(arr, 0, array, 0, arr.size)
array[arr.size] = element
return array
}
EDIT 1: (following Tenfour04's answer)
My adapter:
class CustomAdapter(private var dataSet: List<Parameter?>) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
sealed class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
class TextViewHolder(itemView: View) : ViewHolder(itemView) {
val textViewName: TextView = itemView.findViewById(R.id.parameterName)
val textViewValue: TextView = itemView.findViewById(R.id.parameterValue)
}
class ButtonViewHolder(itemView: View) : ViewHolder(itemView) {
var textViewName: TextView = itemView.findViewById(R.id.parameterName)
val buttonViewValue: Button = itemView.findViewById(R.id.parameterButton)
}
class SpinnerViewHolder(itemView: View) : ViewHolder(itemView) {
val textViewName: TextView = itemView.findViewById(R.id.parameterName)
val spinnerViewValue: Spinner = itemView.findViewById(R.id.parameterSpinner)
}
}
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
return when (viewType) {
0 -> {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.parameter_text, viewGroup, false)
ViewHolder.TextViewHolder(view)
}
1 -> {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.parameter_button, viewGroup, false)
ViewHolder.ButtonViewHolder(view)
}
2 -> {
val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.parameter_spinner, viewGroup, false)
ViewHolder.SpinnerViewHolder(view)
}
else -> throw IllegalArgumentException("Invalid view type")
}
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
when (viewHolder) {
is ViewHolder.TextViewHolder -> {
viewHolder.textViewName.text = dataSet[position]!!.parameterName
viewHolder.textViewValue.text = dataSet[position]!!.parameterValue as CharSequence?
}
is ViewHolder.ButtonViewHolder -> {
viewHolder.textViewName.text = dataSet[position]!!.parameterName
viewHolder.buttonViewValue.text = dataSet[position]!!.parameterValue as CharSequence?
}
is ViewHolder.SpinnerViewHolder -> {
viewHolder.textViewName.text = dataSet[position]!!.parameterName
viewHolder.spinnerViewValue.adapter = dataSet[position]!!.parameterValue as SpinnerAdapter?
}
}
}
override fun getItemViewType(position: Int) : Int {
return dataSet[position]!!.parameterType
}
override fun getItemCount() = dataSet.size
}
In the OnCreate method, I initialize the RecyclerView:
rv_parameters.layoutManager = LinearLayoutManager(this)
rv_parameters.adapter = CustomAdapter(parametersList)
Here is my list of parameters:
private var parametersList = emptyList<Parameter?>()
And finally, here is how I add parameters to this list:
with(rv_parameters.adapter) {
parametersList += ParameterText("Temperature", "24°C")
this?.notifyDataSetChanged()
}
question from:
https://stackoverflow.com/questions/65943212/reyclerview-using-multiple-type-view-doesnt-work