使用 RecyclerView 的多视图 - Kotlin(Android) - 无法切换视图
Posted
技术标签:
【中文标题】使用 RecyclerView 的多视图 - Kotlin(Android) - 无法切换视图【英文标题】:Multiviews using RecycleView - Kotlin(Android) - Unable to switch viewholder 【发布时间】:2020-09-10 07:10:27 【问题描述】:我已经浏览了几天来寻找我的问题的解决方案,但我很困惑,无法弄清楚问题所在。我是 android/Kotlin 的相对初学者,所以请多多包涵。
我有一个如下所示的数据类,我从静态源填充了 pid 值等。
class MyOrderList(var pid: String, var name: String, var imageUrl: String, var size: String, var description: String, val price: Int, var count: Int, var itemtotal: Int)
这个想法基本上是,如果你遍历上面的类列表,pid 通常由一个数字或一个特定的单词表示,例如“LIQUID”。所以在我的列表中,位置 0 会显示 pid = "LIQUID",而位置 1 是一个数字,比如 pid = 2。
我想创建一个 recyclerview,当它在列表中将 LIQUID 视为 pid 时,它将使用 viewholder2 及其自己的布局。否则它将使用 viewholder1 和自己的布局。
问题是我创建的 recyclerview 只显示一个视图。如果位置 0 pid 为 LIQUID,则视图持有者为 ViewHolder2,即使对于列表中 PID 不再为 LIQUID 的后续项目也是如此。简而言之,位置 0 上的 pid 值将决定整个列表的视图。
我还在摸索RecyclerView的曲折,还是没有完全理解。
请看下面的sn-p。
======================
class MyOrderCart(var myOrder: MutableList, var mymutablelist: MutableList): RecyclerView.Adapter()
inner class ViewHolder1(itemView: View) : RecyclerView.ViewHolder(itemView)
fun bindView1(mycartlist: MyOrderList)
itemView.nameView.text = mycartlist.name
itemView.sizeView.text = "Size: $mycartlist.size"
var iprice = mycartlist.price
itemView.priceView.text = "Price: $iprice"
var icount = mycartlist.count
itemView.countView.text = "Count: $icount"
var itotal = mycartlist.itemtotal
itemView.itemtotalView.text = "Subtotal: $itotal"
var image_checkout = itemView.findViewById(R.id.image_checkout) as ImageView
var checkout_deletebutton = itemView.findViewById(R.id.checkout_deletebutton) as ImageButton
var checkout_editcount = itemView.findViewById(R.id.checkout_editcount) as ImageButton
var mytime = System.currentTimeMillis()
try
Glide.with(image_checkout.getContext()).load(mycartlist.imageUrl)
.signature(ObjectKey(mytime)).into(image_checkout)
.clearOnDetach()
finally
image_checkout.setImageResource(R.drawable.noimage)
inner class ViewHolder2(itemView: View) : RecyclerView.ViewHolder(itemView)
fun bindView2(mycartlist: MyOrderList)
itemView.checkout_inside_textview.text = mycartlist.pid
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
var myorderviewtype = myOrder.get(viewType)
return when (myorderviewtype.pid)
"LIQUOR" ->
ViewHolder2(
LayoutInflater.from(parent.context)
.inflate(R.layout.insidecheckout_label, parent, false)
)
"NOODLES" ->
ViewHolder2(
LayoutInflater.from(parent.context)
.inflate(R.layout.insidecheckout_label, parent, false)
)
else ->
ViewHolder1(
LayoutInflater.from(parent.context)
.inflate(R.layout.layout_insidecheckout, parent, false)
)
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int)
val gsonRaw = GsonBuilder().create()
var pos = viewHolder.getAdapterPosition()
var mycartlist: MyOrderList = myOrder.get(position)
when (viewHolder)
is ViewHolder2 ->
val liquorviewHolder = viewHolder as ViewHolder2
liquorviewHolder.bindView2(mycartlist)
is ViewHolder1 ->
val liquorviewHolder = viewHolder as ViewHolder1
liquorviewHolder.bindView1(mycartlist)
【问题讨论】:
【参考方案1】:您还没有覆盖 getItemViewType 方法。试试下面的代码。
override fun getItemViewType(position: Int): Int
return myOrder.get(position).pid
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
return when (viewType)
"LIQUOR" ->
ViewHolder2(
LayoutInflater.from(parent.context)
.inflate(R.layout.insidecheckout_label, parent, false)
)
"NOODLES" ->
ViewHolder2(
LayoutInflater.from(parent.context)
.inflate(R.layout.insidecheckout_label, parent, false)
)
else ->
ViewHolder1(
LayoutInflater.from(parent.context)
.inflate(R.layout.layout_insidecheckout, parent, false)
)
由于您没有使用 getItemViewType 发送 viewType,因此您在 onCreateViewHolder 中总是得到 0。
【讨论】:
谢谢阿什特。 getItemViewType 需要 Int 作为返回类型。但是你的意见对我帮助很大。谢谢!!! pid 不是一个 int 变量吗?【参考方案2】:在您的适配器类中,您需要覆盖getItemViewType
方法。
像这样:
override fun getItemViewType(position: Int): Int
// return view type according to position
// get your pid using position
// return 0 for "LIQUOR", 1 for "NOODLES" and 2 for anything else
// you have to return an integer value only, according to the method signature
然后在 onCreateViewHolder
方法中,使用 int 类型的 viewType 参数来膨胀所需的视图:
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder
return when (viewType)
0 ->
ViewHolder2(
LayoutInflater.from(parent.context)
.inflate(R.layout.insidecheckout_label, parent, false)
)
1 ->
ViewHolder2(
LayoutInflater.from(parent.context)
.inflate(R.layout.insidecheckout_label, parent, false)
)
else ->
ViewHolder1(
LayoutInflater.from(parent.context)
.inflate(R.layout.layout_insidecheckout, parent, false)
)
【讨论】:
嗨,范什。你的推荐有效!!!我做了以下并修改了 oncreateviewholder 以预测 viewtype 值。覆盖 fun getItemViewType(position: Int): Int var mycartlist: MyOrderList = myOrder.get(position) when(mycartlist.pid) "LIQUOR" -> return 1 "NOODLES" -> return 2 else -> 返回 0以上是关于使用 RecyclerView 的多视图 - Kotlin(Android) - 无法切换视图的主要内容,如果未能解决你的问题,请参考以下文章
Android RecyclerView 项目在滚动时随机播放
如何将 ko.validation 错误与相关的视图模型字段名称联系在一起