Android Studio Kotlin:RecyclerView,具有不同数据的多个视图类型

Android Studio Kotlin:RecyclerView,具有不同数据的多个视图类型,android,kotlin,android-recyclerview,Android,Kotlin,Android Recyclerview,我正在创建一个包含多种视图类型的RecyclerView。第一个viewType(ViewType1)采用产品名称、价格和数量。而第二个视图类型(ViewType2)采用产品名称、价格和数量、topping1、topping2、topping3和Topping4 但是,在向recyclerview添加条目时,我收到一个错误,因为没有为参数topping1到4传递任何值: list.add(DataModel("American","1","12.

我正在创建一个包含多种视图类型的RecyclerView。第一个viewType(ViewType1)采用产品名称、价格和数量。而第二个视图类型(ViewType2)采用产品名称、价格和数量、topping1、topping2、topping3和Topping4

但是,在向recyclerview添加条目时,我收到一个错误,因为没有为参数topping1到4传递任何值:

list.add(DataModel("American","1","12.50", ItemAdapter.NO_TOPPING))  //Error recieved for missing params
list.add(DataModel("Romana","1","12.50", "Pepperoni", "Aubergine", "Ex Mozz.", "Salami", ItemAdapter.TOPPINGS_4))
它希望它是ViewType2,而它是ViewType1。如何更改它,使ViewType1不需要包含空参数,只需要传递数据参数productName、productPrice和productQuantity

MainActivity.kt

package com.example.multiplerecyclerview

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*

import kotlinx.android.synthetic.main.item_custom_row.view.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //Set the LayoutManager that this RecyclerView will use.
        recycler_view_items.layoutManager = LinearLayoutManager(this)

        // Adapter class is initialized and list is passed in the param.
        val itemAdapter = ItemAdapter(this, getItemsList())

        //adapter instance is set to the recyclerview to inflate the items.
        recycler_view_items.adapter = itemAdapter
    }

    private fun getItemsList(): ArrayList<DataModel> {
        val list = ArrayList<DataModel>()

        list.add(DataModel("Romana","1","12.50", "Pepperoni", "Aubergine", "Ex Mozz.", "Salami", ItemAdapter.TOPPINGS_4))
        list.add(DataModel("American","1","12.50", ItemAdapter.NO_TOPPING))

        return list
    }
}
package com.example.multiplerecyclerview

class DataModel(val itemName: String, val itemQuantity: String, val itemPrice: String, val topping1: String,  val topping2: String,  val topping3: String,  val topping4: String, val viewType: Int) {
}
package com.example.multiplerecyclerview

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_custom_row.view.*
import kotlinx.android.synthetic.main.item_custom_row4.view.*


class ItemAdapter(val context: Context, val items: ArrayList<DataModel>) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        const val NO_TOPPING = 1
        const val TOPPINGS_4 = 4
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {

        if(viewType == NO_TOPPING) {
            return ViewHolder(
                LayoutInflater.from(context).inflate(
                    R.layout.item_custom_row,
                    parent,
                    false
                )
            )
        } else if (viewType == TOPPINGS_4) {
            return ViewHolder4(
                LayoutInflater.from(context).inflate(
                    R.layout.item_custom_row4,
                    parent,
                    false
                )
            )
        } else {
            return ViewHolder(
                LayoutInflater.from(context).inflate(
                    R.layout.item_custom_row,
                    parent,
                    false
                )
            )
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val item = items.get(position)

        if(holder is ViewHolder) {

            holder.productQuantity.text = item.itemName
            holder.productName.text = item.itemName
            holder.productPrice.text = item.itemPrice

        } else if(holder is ViewHolder4) {

            holder.productQuantity4.text = item.itemName
            holder.productName4.text = item.itemName
            holder.productPrice4.text = item.itemPrice

            holder.topping1.text = item.topping1
            holder.topping2.text = item.topping2
            holder.topping3.text = item.topping3
            holder.topping4.text = item.topping4
        }

    }

    override fun getItemViewType(position: Int): Int {
        return items[position].viewType
    }

    override fun getItemCount(): Int {
        return items.size
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val productQuantity = view.productQuantityView
        val productName = view.productNameView
        val productPrice = view.productPriceView
    }

    class ViewHolder4(view: View) : RecyclerView.ViewHolder(view) {
        val productQuantity4 = view.productQuantityView4
        val productName4 = view.productNameView4
        val productPrice4 = view.productPriceView4

        val topping1 = view.topping1View
        val topping2 = view.topping2View
        val topping3 = view.topping3View
        val topping4 = view.topping4View
    }
}
ItemAdapter.kt

package com.example.multiplerecyclerview

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*

import kotlinx.android.synthetic.main.item_custom_row.view.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //Set the LayoutManager that this RecyclerView will use.
        recycler_view_items.layoutManager = LinearLayoutManager(this)

        // Adapter class is initialized and list is passed in the param.
        val itemAdapter = ItemAdapter(this, getItemsList())

        //adapter instance is set to the recyclerview to inflate the items.
        recycler_view_items.adapter = itemAdapter
    }

    private fun getItemsList(): ArrayList<DataModel> {
        val list = ArrayList<DataModel>()

        list.add(DataModel("Romana","1","12.50", "Pepperoni", "Aubergine", "Ex Mozz.", "Salami", ItemAdapter.TOPPINGS_4))
        list.add(DataModel("American","1","12.50", ItemAdapter.NO_TOPPING))

        return list
    }
}
package com.example.multiplerecyclerview

class DataModel(val itemName: String, val itemQuantity: String, val itemPrice: String, val topping1: String,  val topping2: String,  val topping3: String,  val topping4: String, val viewType: Int) {
}
package com.example.multiplerecyclerview

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_custom_row.view.*
import kotlinx.android.synthetic.main.item_custom_row4.view.*


class ItemAdapter(val context: Context, val items: ArrayList<DataModel>) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        const val NO_TOPPING = 1
        const val TOPPINGS_4 = 4
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {

        if(viewType == NO_TOPPING) {
            return ViewHolder(
                LayoutInflater.from(context).inflate(
                    R.layout.item_custom_row,
                    parent,
                    false
                )
            )
        } else if (viewType == TOPPINGS_4) {
            return ViewHolder4(
                LayoutInflater.from(context).inflate(
                    R.layout.item_custom_row4,
                    parent,
                    false
                )
            )
        } else {
            return ViewHolder(
                LayoutInflater.from(context).inflate(
                    R.layout.item_custom_row,
                    parent,
                    false
                )
            )
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val item = items.get(position)

        if(holder is ViewHolder) {

            holder.productQuantity.text = item.itemName
            holder.productName.text = item.itemName
            holder.productPrice.text = item.itemPrice

        } else if(holder is ViewHolder4) {

            holder.productQuantity4.text = item.itemName
            holder.productName4.text = item.itemName
            holder.productPrice4.text = item.itemPrice

            holder.topping1.text = item.topping1
            holder.topping2.text = item.topping2
            holder.topping3.text = item.topping3
            holder.topping4.text = item.topping4
        }

    }

    override fun getItemViewType(position: Int): Int {
        return items[position].viewType
    }

    override fun getItemCount(): Int {
        return items.size
    }

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val productQuantity = view.productQuantityView
        val productName = view.productNameView
        val productPrice = view.productPriceView
    }

    class ViewHolder4(view: View) : RecyclerView.ViewHolder(view) {
        val productQuantity4 = view.productQuantityView4
        val productName4 = view.productNameView4
        val productPrice4 = view.productPriceView4

        val topping1 = view.topping1View
        val topping2 = view.topping2View
        val topping3 = view.topping3View
        val topping4 = view.topping4View
    }
}
package com.example.multiplerecyclerview
导入android.content.Context
导入android.view.LayoutInflater
导入android.view.view
导入android.view.ViewGroup
导入androidx.core.content.ContextCompat
导入androidx.recyclerview.widget.recyclerview
导入kotlinx.android.synthetic.main.item_custom_row.view*
导入kotlinx.android.synthetic.main.item_custom_row4.view*
类ItemAdapter(val上下文:上下文,val项:ArrayList):
RecyclerView.Adapter(){
伴星{
const val NO_top=1
常量值浇头4=4
}
override fun onCreateViewHolder(父级:ViewGroup,viewType:Int):RecyclerView.ViewHolder{
如果(视图类型==无顶部){
返回视窗座(
放平。从(上下文)。充气(
R.layout.item_custom_行,
父母亲
假的
)
)
}else if(viewType==浇头_4){
返回视图保持器4(
放平。从(上下文)。充气(
R.layout.item_custom_第4行,
父母亲
假的
)
)
}否则{
返回视窗座(
放平。从(上下文)。充气(
R.layout.item_custom_行,
父母亲
假的
)
)
}
}
覆盖onBindViewHolder(holder:RecyclerView.ViewHolder,位置:Int){
val item=items.get(位置)
if(保持架为视图保持架){
holder.productQuantity.text=item.itemName
holder.productName.text=item.itemName
holder.productPrice.text=item.itemPrice
}else if(保持架为ViewHolder4){
holder.productQuantity4.text=item.itemName
holder.productName4.text=item.itemName
holder.ProductPrice 4.text=item.itemPrice
holder.topping1.text=项目.topping1
holder.topping2.text=item.topping2
holder.topping3.text=项目.topping3
holder.topping4.text=项目.topping4
}
}
覆盖getItemViewType(位置:Int):Int{
返回项目[位置].viewType
}
重写getItemCount():Int{
返回项目。大小
}
类ViewHolder(视图:视图):RecyclerView.ViewHolder(视图){
val productQuantity=view.productQuantityView
val productName=view.productNameView
val productPrice=view.productPriceView
}
类ViewHolder4(视图:视图):RecyclerView.ViewHolder(视图){
val productQuantity4=view.productQuantityView4
val productName4=view.productNameView4
val productPrice4=view.productPriceView4
val topping1=视图。topping1视图
val topping2=视图。topping2视图
val topping3=视图。topping3视图
val topping4=视图。topping4视图
}
}
项目\自定义\行

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/cardViewItem1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:padding="10dp"
    android:layout_margin="4dp"
    app:cardElevation="10dp"
    app:cardCornerRadius="8dp"
    app:cardPreventCornerOverlap="false">

    <RelativeLayout
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:padding="12dp">

        <TextView
            android:id="@+id/productQuantityView"
            android:layout_width="wrap_content"
            android:layout_height="45dp"
            android:layout_marginLeft="10dp"
            android:layout_marginEnd="15dp"
            android:text="1"
            android:textColor="#881b32"
            android:textSize="25sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/productNameView"
            android:layout_width="wrap_content"
            android:layout_height="46dp"
            android:layout_marginEnd="10dp"
            android:layout_toEndOf="@+id/productQuantityView"
            android:text="12'' Killiney Beach"
            android:textColor="#881b32"
            android:textSize="20sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/productPriceView"
            android:layout_width="wrap_content"
            android:layout_height="52dp"
            android:layout_marginEnd="20dp"
            android:layout_toEndOf="@id/productNameView"
            android:text="14.50"
            android:textColor="#fcac52"
            android:textSize="18sp"
            android:textStyle="bold" />

    </RelativeLayout>

</androidx.cardview.widget.CardView>

项目\u自定义\u行4

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/cardViewItem4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="4dp"
    app:cardElevation="10dp"
    app:cardCornerRadius="8dp"
    app:cardPreventCornerOverlap="false">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="12dp">

        <TextView
            android:id="@+id/productQuantityView4"
            android:layout_width="wrap_content"
            android:layout_height="45dp"
            android:layout_marginLeft="10dp"
            android:layout_marginEnd="15dp"
            android:text="1"
            android:textColor="#881b32"
            android:textSize="25sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/productNameView4"
            android:layout_width="wrap_content"
            android:layout_height="46dp"
            android:layout_marginEnd="10dp"
            android:layout_toEndOf="@+id/productQuantityView4"
            android:text="12'' Killiney Beach"
            android:textColor="#881b32"
            android:textSize="20sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/productPriceView4"
            android:layout_width="wrap_content"
            android:layout_height="52dp"
            android:layout_marginEnd="20dp"
            android:layout_toEndOf="@id/productNameView4"
            android:text="14.50"
            android:textColor="#881b32"
            android:textSize="18sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/topping1View"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_marginStart="20dp"
            android:layout_marginTop="3dp"
            android:layout_toEndOf="@+id/productPriceView4"
            android:text="Pepperoni"
            android:textColor="#fcac52"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/topping2View"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/topping1View"
            android:layout_marginStart="20dp"
            android:layout_marginTop="13dp"
            android:layout_toEndOf="@+id/productPriceView4"
            android:text="Aubergine"
            android:textColor="#fcac52"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/topping3View"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_marginStart="20dp"
            android:layout_marginTop="3dp"
            android:layout_toEndOf="@+id/topping1View"
            android:text="Semi Dried Tomatos"
            android:textColor="#fcac52"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/topping4View"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/topping1View"
            android:layout_marginStart="20dp"
            android:layout_marginTop="13dp"
            android:layout_toEndOf="@+id/topping2View"
            android:text="Smoked Applewood"
            android:textColor="#fcac52"
            android:textSize="14sp"
            android:textStyle="bold" />

    </RelativeLayout>

</androidx.cardview.widget.CardView>

为参数指定默认值:

class DataModel(val itemName: String, 
val itemQuantity: String, 
val itemPrice: String, 
val topping1: String = "", 
val topping2: String = "", 
val topping3: String = "",  
val topping4: String = "", 
val viewType: Int) {
    }

您可以将其重构为一个数据类

data class DataModel(val itemName: String,
val itemQuantity: String,
val itemPrice: String, 
val topping1: String = "",  
val topping2: String = "",  
val topping3: String = "",  
val topping4: String = "", 
val viewType: Int)
您还可以在此处使用可为null的变量,因为它们可能为null:

data class DataModel(val itemName: String,
val itemQuantity: String, 
val itemPrice: String, 
val topping1: String? = null,
val topping2: String? = null,  
val topping3: String? = null, 
val topping4: String? = null, 
val viewType: Int)
然后,由于kotlin具有命名参数,您可以执行以下操作:

  val foo = DataModel("American","1","12.50", viewType = ItemAdapter.NO_TOPPING )