使用 RecyclerView 的多视图 - Kotlin(Android) - 无法切换视图持有者
Multiviews using RecycleView - Kotlin(Android) - Unable to switch viewholder
我已经浏览了几天来寻找我的问题的解决方案,但我很困惑,无法找出问题所在。我是 Android/Kotlin 的相对初学者,所以请多多包涵。
我有一个数据 class 如下所示,我从静态源填充了 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:整数)
这个想法基本上是,如果您遍历上面的 class 列表,pid 通常由数字或特定单词表示,例如 "LIQUID"。所以在我的列表中,位置 0 将显示 pid = "LIQUID",位置 1 是一个数字,比如 pid = 2.
我想创建一个 recyclerview,当它在列表中看到 LIQUID 作为 pid 时,它将使用具有自己布局的 viewholder2。否则它将使用带有自己布局的 viewholder1。
问题是我创建的recyclerview 只显示一个viewholder。如果位置 0 pid 是 LIQUID,则 viewholder 是 ViewHolder2,即使对于列表中 PID 不再是 LIQUID 的后续项目也是如此。简而言之,位置 0 上的 pid 值将决定整个列表的查看器。
我还在琢磨RecyclerView的曲折,还没完全看懂。
请看下面的片段。
=====================
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)
}
}
}
嘿,您还没有覆盖 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。
在您的适配器 class 中,您需要覆盖 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)
)
}
}
}
我已经浏览了几天来寻找我的问题的解决方案,但我很困惑,无法找出问题所在。我是 Android/Kotlin 的相对初学者,所以请多多包涵。
我有一个数据 class 如下所示,我从静态源填充了 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:整数)
这个想法基本上是,如果您遍历上面的 class 列表,pid 通常由数字或特定单词表示,例如 "LIQUID"。所以在我的列表中,位置 0 将显示 pid = "LIQUID",位置 1 是一个数字,比如 pid = 2.
我想创建一个 recyclerview,当它在列表中看到 LIQUID 作为 pid 时,它将使用具有自己布局的 viewholder2。否则它将使用带有自己布局的 viewholder1。
问题是我创建的recyclerview 只显示一个viewholder。如果位置 0 pid 是 LIQUID,则 viewholder 是 ViewHolder2,即使对于列表中 PID 不再是 LIQUID 的后续项目也是如此。简而言之,位置 0 上的 pid 值将决定整个列表的查看器。
我还在琢磨RecyclerView的曲折,还没完全看懂。
请看下面的片段。
=====================
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)
}
}
}
嘿,您还没有覆盖 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。
在您的适配器 class 中,您需要覆盖 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)
)
}
}
}